[英]How do I display the cropped part using react-image-crop- It appears as a black image of the cropped portion
function getCroppedImg(){
console.log('inside getCroppedImg')
const canvas = document.createElement("canvas");
const image = document.createElement("image");
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
);
const base64Image = canvas.toDataURL("image/jpeg", 1);
setResult(base64Image);
};
const [srcImg, setSrcImg] = useState(null);
const [image, setImage] = useState(null);
const [crop, setCrop] = useState({aspect: 16 / 9});
const [result, setResult] = useState(null);
const handleImage = event => {
setSrcImg(URL.createObjectURL(event.target.files[0]));
console.log(event.target.files[0]);
};
return (
<div>
{srcImg && (
<div>
<ReactCrop src={srcImg} onLoad={setImage} crop={crop} onChange={(crop) => setCrop(crop)}>
<img src={srcImg}/>
</ReactCrop>
<button className="cropButton" onClick={getCroppedImg}>crop</button>
</div>)}
{result && (
<div>
<img src={result} alt="cropped image"/>
</div>
=)}
</div>)
上面是點擊裁剪按鈕時調用的 function。 但它返回的是黑色圖像。 我想用“結果”來顯示它。 基本上我正在嘗試輸入圖像,點擊裁剪按鈕裁剪的部分應該顯示在{result}
中。 我不介意它是否也作為預覽出現,比如動態裁剪預覽。
顯示為黑色圖像。 我該如何解決?
處理圖像的不錯的庫
因此,根據他們的官方文檔https://www.npmjs.com/package/react-image-crop沒有內置的方式來顯示裁剪區域“我如何在瀏覽器中生成裁剪預覽?這不是圖書館的一部分”
另一方面,他們提供了帶有“裁剪預覽”實現的實例: https://codesandbox.io/s/react-image-crop-demo-with-react-hooks-y831o?file=/src/App.tsx: 3989-4188
在我這邊,我決定使用 crop preview-s 來簡化一些工作,並為此實現了額外的組件。 我使用上面的代碼示例作為參考。
import { useEffect, useRef } from 'react';
import { canvasPreview } from './canvasPreview';
export default function CropPreview({ img, crop }) {
const canvasRef = useRef(null);
useEffect(() => {
if (!crop?.width || !crop?.height || !img || !canvasRef.current) {
return;
}
canvasPreview(img, canvasRef.current, crop, 1, 0);
}, [img, crop]);
if (!!crop && !!img) {
return <canvas ref={canvasRef} />;
}
}
它的用法:
import { useRef, useState } from 'react';
import CropPreview from './CropPreview';
import ReactCrop from 'react-image-crop';
function App() {
const imgRef = useRef(null);
const [crop, setCrop] = useState();
const [completedCrop, setCompletedCrop] = useState();
return (
<>
<div style={{ maxWidth: '500px' }}>
<ReactCrop
crop={crop}
onChange={setCrop}
onComplete={(c) => setCompletedCrop(c)}
>
<img
crossOrigin="anonymous"
ref={imgRef}
src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1024px-Image_created_with_a_mobile_phone.png"
/>
</ReactCrop>
</div>
<CropPreview img={imgRef.current} crop={completedCrop} />
</>
);
}
export default App;
canvasPreview.js 是從上面的實例中“按原樣”獲取的,只刪除了一些特定於打字稿的代碼片段(我在沒有 TS 的情況下創建了這個組件):
const TO_RADIANS = Math.PI / 180;
export async function canvasPreview(
image,
canvas,
crop,
scale = 1,
rotate = 0
) {
const ctx = canvas.getContext('2d');
if (!ctx) {
throw new Error('No 2d context');
}
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
// devicePixelRatio slightly increases sharpness on retina devices
// at the expense of slightly slower render times and needing to
// size the image back down if you want to download/upload and be
// true to the images natural size.
const pixelRatio = window.devicePixelRatio;
// const pixelRatio = 1
canvas.width = Math.floor(crop.width * scaleX * pixelRatio);
canvas.height = Math.floor(crop.height * scaleY * pixelRatio);
ctx.scale(pixelRatio, pixelRatio);
ctx.imageSmoothingQuality = 'high';
const cropX = crop.x * scaleX;
const cropY = crop.y * scaleY;
const rotateRads = rotate * TO_RADIANS;
const centerX = image.naturalWidth / 2;
const centerY = image.naturalHeight / 2;
ctx.save();
// 5) Move the crop origin to the canvas origin (0,0)
ctx.translate(-cropX, -cropY);
// 4) Move the origin to the center of the original position
ctx.translate(centerX, centerY);
// 3) Rotate around the origin
ctx.rotate(rotateRads);
// 2) Scale the image
ctx.scale(scale, scale);
// 1) Move the center of the image to the origin (0,0)
ctx.translate(-centerX, -centerY);
ctx.drawImage(
image,
0,
0,
image.naturalWidth,
image.naturalHeight,
0,
0,
image.naturalWidth,
image.naturalHeight
);
ctx.restore();
}
使用此解決方案,您將能夠在 canvas 上顯示當前裁剪。
我不太清楚為什么您最初嘗試在 canvas 上繪制當前作物,然后在圖像上從 canvas 繪制當前作物。 但是,如果出於某種原因這很重要——像下面這樣的代碼片段會將裁剪從 canvas“轉移”到圖像:
canvasRef.current.toBlob((blob) => {
const url = URL.createObjectURL(blob);
const image = document.createElement('img');
document.body.appendChild(image);
image.onload = function () {
URL.revokeObjectURL(url);
};
image.src = url;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.