Wczytywanie obrazka z komputera użytkownika

0

cześć
w ramach małego projektu w CamanJS i Vue 3 chcę zrobić prostą aplikację do manipulacji zdjęciami. Najpierw chciałbym zrobić wybieranie obrazka z dysku za pomocą inputa, a potem wyświetlenie i przepisanie jego ścieżki do zmiennej. Póki co mam tyle napisane.
Błąd pojawia się w tym kawałku:

document.querySelector("input[type=file]").files[0];
const previewPicture = ref();

    const fileAdded = () => {
      const file = document.querySelector("input[type=file]").files[0];
      const reader = new FileReader();

      reader.addEventListener(
        "load",
        () => {
          console.log("Loaded image from disk...");
          // convert image file to base64 string
          previewPicture.value.src = reader.result;
        },
        false
      );

      if (file) {
        reader.readAsDataURL(file);
      }
    };
0
  1. Input file też lepiej przypisać do refa (po to one są).
  2. Co mówi błąd?

Jak fileAdded wywołujesz przy wybraniu pliku i jest zbindowane do inputa, to jako parametr powinien iść event do funkcji.

0

udało mi się ruszyć do przodu trochę, musiałem zmienić <script lang="ts"> na <script> w Vue, dzięki temu mam dostęp do files[0]
ps. zrobię wg tego poradnika https://piyushsinha.tech/image-editor-using-camanjs

1
Krwawy Ork napisał(a):

udało mi się ruszyć do przodu trochę, musiałem zmienić <script lang="ts"> na <script> w Vue, dzięki temu mam dostęp do files[0]

Żeby działało to po stronie TypeScriptu musisz go poinformować, że querySelector (albo jeszcze lepiej jak będzie to ref) przechowuje znacznik <input type="file">

Jeśli masz pewność, że na 100% uda się pobrać pole, bo querySelector może zwrócić null

const file = (document.querySelector("input[type=file]") as HTMLInputElement).files[0];

lub jeśli nie masz takiej gwarancji

const file = document.querySelector<HTMLInputElement>("input[type=file]");

// file.files[0] <-- TypeScript nas poinformuje, że właściwość "files" może być nieprawidłowa

if (file) {
  // file.files[0] <-- Dlatego potrzebny nam warunek, żeby to sprawdzić
}

Podobnie jest z ref

const file = ref<HTMLInputElement>();
0

ok udało mi się zrobić wczytywanie, jeszcze mam w planie wczytanie obrazka za pomocą drag & drop ale to na inny czas, wrzucam cały kod może komuś się sprzyda:

<script lang="ts">
import { defineComponent, ref, reactive } from "vue";

export default defineComponent({
  setup() {
    const pictureSettings = reactive({
      height: 500,
      width: 600,
    });

    const loadedPicture = ref<String | ArrayBuffer>();
    const pictureName = ref<String>();

    const fileAdded = () => {
      console.log("Something has happened!");

      const file = (document.getElementById("image-input") as HTMLInputElement)
        .files[0];

      const reader = new FileReader();

      if (file) {
        pictureName.value = file.name;
        reader.readAsDataURL(file);
      }

      reader.onload = () => {
        console.log("reader onLoad!");
        loadedPicture.value = reader.result;
      };
    };

    const scaleUp = () => {
      pictureSettings.height += 100;
      pictureSettings.width += 100;
    };

    const scaleDown = () => {
      pictureSettings.height -= 100;
      pictureSettings.width -= 100;
    };

    return {
      loadedPicture,
      pictureName,
      pictureSettings,
      fileAdded,
      scaleUp,
      scaleDown,
    };
  },
});
</script>

<template>
  <div>
    <h1>Welcome to ImagePreview component!</h1>
    <input id="image-input" type="file" @change="fileAdded" />
    <button @click="scaleUp">Scale up</button>
    <button @click="scaleDown">Scale down</button>
    <section>
      <h1>{{ pictureName }}</h1>
      <img
        :src="loadedPicture"
        :width="pictureSettings.width"
        :height="pictureSettings.height"
      />
    </section>
  </div>
</template>

<style>
</style>

1 użytkowników online, w tym zalogowanych: 0, gości: 1