UGA Boxxx

つぶやきの延長のつもりで、知ったこと思ったこと書いてます

【react-dropzone】preview画像の横幅と縦幅を取得する

react-dropzoneでpreviewすることができるのはわかったので、今度はそのpreview中の画像の横幅と縦幅を取得したい

uga-box.hatenablog.com

プレビュー画像の横幅と縦幅を取得するには、<img> 要素の naturalWidth と naturalHeight プロパティを使用する

これらのプロパティは、画像の元のサイズ(画像ファイルの実際の幅と高さ)を提供する

react-dropzone を使用してファイルをアップロードし、プレビュー画像の横幅(および縦幅)を取得する方法は以下

概要

  1. react-dropzoneでファイルをドロップしたときにファイル情報を取得
  2. 画像のプレビューを表示
  3. 画像のnaturalWidthとnaturalHeightをimg.onloadイベントで取得
import React, { useState, useCallback } from 'react';
import { useDropzone } from 'react-dropzone';

const ImageDropzone = () => {
  const [imageSrc, setImageSrc] = useState(null);
  const [imageDimensions, setImageDimensions] = useState({ width: 0, height: 0 });

  const onDrop = useCallback((acceptedFiles) => {
    // 画像ファイルを取得
    const file = acceptedFiles[0];
    const objectURL = URL.createObjectURL(file);
    
    // プレビュー用に画像のURLをセット
    setImageSrc(objectURL);
    
    // 画像の読み込みが完了した後に横幅と縦幅を取得
    const img = new Image();
    img.src = objectURL;
    img.onload = () => {
      setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight });

      // 不要になったオブジェクトURLを解放
      URL.revokeObjectURL(objectURL);
    };
  }, []);

  const { getRootProps, getInputProps } = useDropzone({ onDrop });

  return (
    <div>
      {/* Dropzone */}
      <div {...getRootProps()} style={{ border: '2px dashed #cccccc', padding: '20px', textAlign: 'center' }}>
        <input {...getInputProps()} />
        <p>Drag 'n' drop some files here, or click to select files</p>
      </div>

      {/* プレビュー画像 */}
      {imageSrc && (
        <div>
          <h4>Preview</h4>
          <img src={imageSrc} alt="Preview" />
          <p>Width: {imageDimensions.width}px, Height: {imageDimensions.height}px</p>
        </div>
      )}
    </div>
  );
};

export default ImageDropzone;

解説

  1. useDropzone の使用: React HookであるuseDropzoneを使い、ファイルのドロップや選択をハンドリング
  2. ファイルのプレビュー表示: URL.createObjectURL()を使って、選択された画像ファイルのプレビューを作成し、<img>タグにセット
  3. 画像の横幅・縦幅を取得: 画像の読み込みが完了したら、img.onloadイベントで画像のnaturalWidthnaturalHeightを取得し、状態管理フック (useState) を通じて表示
  4. 不要なURLの解放: 画像の使用が終わったらURL.revokeObjectURL()を使ってメモリを解放

これで react-dropzoneを使用してプレビュー画像の横幅と縦幅を動的に取得することができる