v2.5.2
Giriş yap

react-image-crop kütüphanesiyle croplanmış olan resmin kaydedilmesi

fatih255
456 defa görüntülendi ve 1 kişi tarafından değerlendirildi

react-image-crop kütüphanesini kullanarak müşteri için ürünlerini yükleyebildiği ve ürün resimlerini boyutlandırabileceği bir cms yazmakla uğraşıyordum. 2 gündür deniyorum olmuyor. Sorum biraz frontend i kapsıyor.


  const handleOnCropComplete = (crop, pixelCrop) => {
        const croppedImg = getCroppedImg(productImage, crop, 'test');
        console.log(croppedImg);
    }

resim crop işlemi yapıldıktan sonra bu üste gördüğümüz fonksiyon çalışyor ve bunun ardından getCroppedImg isimli farklı bir fonksiyona :
state de bulunan productImage (file inputtan alınan resmin blob u)
crop parametresi kütüphanenın sagladıgı bir parametre kesılen alanın verısını verıyor
test yazdıgım kısımda fıleName kısmı oda resmımızın ısmı oluyor.

hatam ctx.drawImage ... kısmında oluşuyor hata kodu şu şekilde:

 TypeError: Failed to execute 'drawImage' 
 on 'CanvasRenderingContext2D': 
 The provided value is not of type '(CSSImageValue or HTMLImageElement 
 or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or 
 ImageBitmap or OffscreenCanvas or VideoFrame)'

blob oldugundan bende mantıklı olarak new Image() kullanarak HTML elementı olusturdum fakat olmadı

AddProductScreen.js

 import React, { useState, useEffect } from 'react'
import { RiAddFill } from 'react-icons/ri';
import 'react-image-crop/dist/ReactCrop.css';
import ReactCrop from 'react-image-crop';
function AddProductScreen() {

    const [productImage, setproductImage] = useState(null);
    const [crop, setCrop] = useState({ aspect: 16 / 9 });
    const [OnImageLoaded, setOnImageLoaded] = useState(null);



    const SelectImageHandler = async (e) => {
    const objectURL = URL.createObjectURL(e.target.files[0])
    setproductImage(objectURL);

  
   
    }
    const handleOnCropComplete = (crop, pixelCrop) => {
        const croppedImg = getCroppedImg(productImage, crop, 'test');
        console.log(croppedImg);
    }


    function getCroppedImg(image, crop, fileName) {
        const canvas = document.createElement('canvas');
        const scaleX = image.naturalWidth / image.width;
        const scaleY = image.naturalHeight / image.height;
        canvas.width = crop.width;
        canvas.height = crop.height;
        const ctx = canvas.getContext('2d');

        ctx.drawImage(
            image,
            crop.x * scaleX,
            crop.y * scaleY,
            crop.width * scaleX,
            crop.height * scaleY,
            0,
            0,
            crop.width,
            crop.height,
        );

        // As Base64 string
        // const base64Image = canvas.toDataURL('image/jpeg');

        // As a blob
        return new Promise((resolve, reject) => {
            canvas.toBlob(blob => {
                blob.name = fileName;
                resolve(blob);
            }, 'image/jpeg', 1);
        });
    }



    function CropDemo({ src }) {

        return <ReactCrop src={src} crop={crop}
            onChange={newCrop => setCrop(newCrop)}
            onComplete={handleOnCropComplete}
            onImageLoaded={image => setOnImageLoaded(setOnImageLoaded({ crop: { width: image.width, height: image.height } }))}
        />;
    }


    return (
        <div className="inner-container flex-row">
            <form>
                <div>
                    <label for="">Ürün Adı</label>
                    <input type="text" />
                </div>
                <div>
                    <label for="">Ürün Kategorisi</label>
                    <select>
                        <option value="">Anadolu Halısı</option>
                        <option value="">A Halısı</option>
                        <option value="">B Halısı</option>
                    </select>
                </div>
                <div>
                    <label for="">Ürün Resmi</label>
                    <input onChange={(e) => SelectImageHandler(e)} type="file" />
                    {CropDemo({ src: productImage })}

                </div>
                <button className="add-btn"><RiAddFill />Ürünü Ekle</button>
            </form>
            <div className="addProduct-preview">
                <div className="preview-box">
                    <div className="productHeader">
                        <span>Ürün Adı</span>
                        <small>Ürün Kategorisi</small>
                    </div>
                    <div className="preview-image-box">

                    </div>

                </div>
            </div>
        </div>
    )
}

export default AddProductScreen

package.json

 {
  "name": "saricalar-stok-yonetimi",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-icons": "^4.2.0",
    "react-image-crop": "^8.6.12",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.3",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

yardımcı olabilirseniz mutlu olurum :) iyi calismalar diliyorum

Cevap yaz
Cevaplar (3)
akincankoc
1047 gün önce

getCroppedImg bu fonksiyona dikkatli bakarsan bir Promise döndürüyorsun hata alman çok normal onun yerine şunu mantıkda ilerleyebilirsin
yazılan method'un resolvunun yerine direk olarak blob olarak gönderebilirsin belki ?

fatih255
1047 gün önce

        const myimage = new Image();
        myimage.src = image;


        console.log(myimage.naturalWidth, myimage.naturalHeight, crop.width, crop.height)
        const canvas = document.createElement('canvas');
        const scaleX = myimage.naturalWidth / onImageLoaded.crop.width;
        const scaleY = myimage.naturalHeight / onImageLoaded.crop.height;
        canvas.width = crop.width;
        canvas.height = crop.height;
        const ctx = canvas.getContext('2d');



        ctx.drawImage(
            myimage,
            crop.x * scaleX,
            crop.y * scaleY,
            crop.width * scaleX,
            crop.height * scaleY,
            0,
            0,
            crop.width,
            crop.height,
        );




        // As Base64 string
        return canvas.toDataURL('image/jpeg');

        // As a blob
        /* 
         return new Promise((resolve, reject) => {
             canvas.toBlob(blob => {
                 blob.name = fileName;
                 resolve(blob);
             }, 'image/jpeg', 1);
         });*/

çözümü bu şekilde takılan arkadaşlara destek olsun cok ugrastırdı. Burada öğrendiğim şey canvasa bir resim cizmek istediğimizde HTML ımage olarak yenı bır element olusturmak sonrasında da tabi farklı sorunlarlada karşılastım mesela cropladıgım alanın degerleri tam optimize olmuyordu suan sorunsuz calısıyor teşekkürler kardeşim herkese iyi çalışmalar

fatih255
1047 gün önce

dedigini dikkate alarak tekrar bi deneme yaptıp canvasta blob kullanamıyor muyuz acaba cünkü ben normalde canvasa resim cizdirmek istediğimde new Image() dıyerek HTML ımage elementı olusturarak onu draw edıyordum. bi kez daha deniyim insallah olur bu sefer