2

我正在尝试在反应应用程序中裁剪图像。我目前正在使用一个名为 react-image-crop 的库,但裁剪后的图像似乎与浏览器上的裁剪区域大小完全相同,这意味着如果我调整浏览器窗口的大小,图像的相同区域的大小会有所不同. 有什么方法可以保留原始图像的分辨率并且仍然能够在客户端进行裁剪?下图是在不同浏览器尺寸下对图片同一区域进行裁剪的结果。

我几乎使用开箱即用的 react-image-crop 和以下裁剪参数

 const [crop, setCrop] = useState({unit: '%', width: 100, aspect: 16 / 9 });

在此处输入图像描述

4

4 回答 4

0

在演示的钩子版本中,替换 getResizedCanvas (并将其移动到反应模块中)修复了问题

const getResizedCanvas = () => {
    const scaleX = imgRef.current.naturalWidth / imgRef.current.width;
    const scaleY = imgRef.current.naturalHeight / imgRef.current.height;
    const tmpCanvas = document.createElement("canvas");
    tmpCanvas.width = Math.ceil(crop.width*scaleX);
    tmpCanvas.height = Math.ceil(crop.height*scaleY);

    const ctx = tmpCanvas.getContext("2d");
    const image = imgRef.current;
    ctx.drawImage(
        image,
        crop.x * scaleX,
        crop.y * scaleY,
        crop.width * scaleX,
        crop.height * scaleY,
        0,
        0,
        crop.width*scaleX,
        crop.height*scaleY,
    );

    return tmpCanvas;
}
于 2020-06-30T16:33:43.780 回答
0

我对割草机也有同样的问题。但是然后将缩放的高度和宽度添加到画布和 drawImage 方法对我有用。

检查下面的屏幕截图。

裁剪时的图像: 裁剪 裁剪时的图像 后的图像分辨率: 裁剪后的图像分辨率

const createCropPreview = async (image, crop, fileName) => {
    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;
    const canvas = document.createElement("canvas");

    canvas.width = Math.ceil(crop.width * scaleX);
    canvas.height = Math.ceil(crop.height * scaleY);

    const ctx = canvas.getContext("2d");

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

    return new Promise((resolve, reject) => {
      canvas.toBlob((blob) => {
        if (blob) {
          blob.name = fileName;
          window.URL.revokeObjectURL(previewUrl);
          const obj = window.URL.createObjectURL(blob);
          setPreviewUrl(obj);
          props.setImg(obj, blob);
        }
      }, "image/jpeg");
    });
  };
于 2021-06-02T10:29:29.430 回答
0

实际上我有同样的问题,我也使用 react-image-crop。我目前的解决方案是创建一个以 px 为单位的静态大小的模式作为裁剪窗口。因此,如果窗口大小较小,则会激活模态溢出。

或多或少像这样: 在此处输入图像描述

因此滚动条会根据窗口大小动态变化,并且不会影响图像大小。

如果有一个真正更好的解决方案,也许我也想听听它:)

于 2020-06-26T04:32:20.903 回答
0

对我来说,这实际上是固定的(使用钩子)。基本上,我正在计算画布大小,同时考虑到当前显示设备的物理像素的窗口分辨率和 CSS 像素的分辨率。

const canvas = document.createElement('canvas')
const crop = completedCrop

const scaleX = image.naturalWidth / image.width
const scaleY = image.naturalHeight / image.height
const ctx = canvas.getContext('2d')
const pixelRatio = window.devicePixelRatio

canvas.width = scaleX * crop.width * pixelRatio
canvas.height = scaleY * crop.height * pixelRatio
ctx.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0)
ctx.imageSmoothingQuality = 'high'

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

您还可以将画布 blob 导出为 png(无损)而不是 jpeg,这将为您提供更好的图像。

canvas.toBlob(
  blob => {
    const img = URL.createObjectURL(blob)
    // do whatever you want...
  },
  'image/png',
  1
)
于 2022-01-26T13:37:45.483 回答