Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 画布旋转、toDataUrl,然后裁剪会破坏图像质量_Javascript_Image_Image Processing_Canvas - Fatal编程技术网

Javascript 画布旋转、toDataUrl,然后裁剪会破坏图像质量

Javascript 画布旋转、toDataUrl,然后裁剪会破坏图像质量,javascript,image,image-processing,canvas,Javascript,Image,Image Processing,Canvas,我有一个图像,我允许用户在任何方向旋转90度。每次它们旋转时,我都使用canvas执行图像操作,然后保存canvas.toDataURLimage/png返回的数据,1 问题是每次旋转图像时图像质量都会降低 我的最终目标是在不损失图像质量的情况下旋转矩形图像,并保存新的数据url function rotateAndSave(image: HTMLImageElement, degrees: number): string { const imageWidth = image.natural

我有一个图像,我允许用户在任何方向旋转90度。每次它们旋转时,我都使用canvas执行图像操作,然后保存canvas.toDataURLimage/png返回的数据,1

问题是每次旋转图像时图像质量都会降低

我的最终目标是在不损失图像质量的情况下旋转矩形图像,并保存新的数据url

function rotateAndSave(image: HTMLImageElement, degrees: number): string {
  const imageWidth = image.naturalWidth;
  const imageHeight = image.naturalHeight;
  const startedHorizontalEndedVertical = imageWidth > imageHeight;
  const canvasSize = startedHorizontalEndedVertical ? imageWidth : imageHeight;

  const canvas = document.createElement("canvas");
  canvas.width = canvasSize;
  canvas.height = canvasSize;

  const ctx = canvas.getContext("2d");
  ctx.setTransform(1, 0, 0, 1, 0, 0);
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // center and rotate canvas
  const translateCanvas = canvasSize / 2;
  ctx.translate(translateCanvas, translateCanvas);
  ctx.rotate(degrees * Math.PI / 180);

  // draw from center
  const translateImageX = startedHorizontalEndedVertical ? -translateCanvas : (-imageWidth / 2);
  const translateImageY = startedHorizontalEndedVertical ? (-imageHeight / 2) : -translateCanvas;
  ctx.drawImage(image, translateImageX, translateImageY); 

  // I got 'cropPlusExport' from another stackoverflow question.
  function cropPlusExport(img, cropX, cropY, cropWidth, cropHeight) {
    // create a temporary canvas sized to the cropped size
    const canvas1 = document.createElement('canvas');
    canvas1.width = cropWidth;
    canvas1.height = cropHeight;
    const ctx1 = canvas1.getContext('2d');
    ctx1.setTransform(1, 0, 0, 1, 0, 0);
    ctx1.clearRect(0, 0, canvas1.width, canvas1.height);
    // use the extended from of drawImage to draw the
    // cropped area to the temp canvas
    ctx1.drawImage(img, cropX, cropY, cropWidth, cropHeight, 0, 0, cropWidth, cropHeight);
    return canvas1.toDataURL("image/png", 1);
  }

  // Start Cropping
  let squareImage = new Image();
  squareImage.src = canvas.toDataURL("image/png", 1);
  squareImage.onload = () => {
    const sx = startedHorizontalEndedVertical ? ((canvasSize - imageHeight) / 2) : 0;
    const sy = startedHorizontalEndedVertical ? 0 : ((canvasSize - imageWidth) / 2);
    const sw = imageHeight;
    const sh = imageWidth;
    const data = cropPlusExport(squareImage, sx, sy, sw, sh);

    // Update DOM via angular binding...
    const dataUrl = data.split(",")[1];
    this.imageSource = dataUrl;

    squareImage = null;
  }
示例html

<div class="view">
  <img [src]="imageSource" />
</div>

请记住,我正在裁剪图像的自然宽度和高度。所以,奇怪的是,如果我不裁剪,那么图像质量不会改变,但是当我裁剪时,图像质量会改变。

画布绘制是有损的,旋转图像会导致像素的硬修改。因此,实际上,如果总是从最后一个状态开始,那么最终会向图像中添加越来越多的瑕疵

只需将原始图像存储在某个位置,并始终从那里开始,而不是使用修改后的版本

//会循环发射吗 img.onload=e=>elem.rotateAndSave1; 常数={ //存储原始图像的副本 原始图像:img.cloneNode, 角度:0, 旋转角度{ //始终使用存储的原始图像 const image=this.originalimage; //跟踪当前变换 该角度+=度; 常量imageWidth=image.naturalWidth; 常量imageHeight=image.naturalHeight; const startedHorizontalEndedVertical=图像宽度>图像高度; const canvasSize=开始水平方向?图像宽度:图像高度; const canvas=document.createElementcanvas; canvas.width=画布大小; canvas.height=画布大小; const ctx=canvas.getContext2d; ctx.setTransform1,0,0,1,0,0; ctx.clearRect0,0,canvas.width,canvas.height; //居中并旋转画布 const translateCanvas=画布大小/2; ctx.translatetranslateCanvas,translateCanvas; ctx.rotatethis.angle*Math.PI/180; //居中抽签 const translateImageX=开始的水平方向广告?-translateCanvas:-imageWidth/2; const translateImageY=开始的水平方向性?-图像高度/2:-平移角度; ctx.drawImageimage、translateImageX、translateImageY; //我从另一个stackoverflow问题中得到了“cropPlusExport”。 函数:img、cropX、cropY、cropWidth、cropHeight{ //创建一个临时画布,其大小为裁剪后的大小 const canvas1=document.createElement'canvas'; 画布1.宽度=宽度; canvas1.height=cropHeight; const ctx1=canvas1.getContext'2d'; ctx1.setTransform1,0,0,1,0,0; ctx1.clearRect0,0,canvas1.width,canvas1.height; //使用drawImage的扩展from来绘制 //临时画布上的裁剪区域 ctx1.img,cropX,cropY,cropWidth,cropHeight,0,0,cropWidth,cropHeight; return canvas1.toDataURLimage/png,1; } //开始收割 让正方形图像=新图像; squareImage.src=canvas.toDataURLimage/png,1; squareImage.onload==>{ const sx=开始的水平方向?画布尺寸-图像高度/2:0; const sy=开始的水平方向广告?0:画布大小-图像宽度/2; const sw=图像高度; 常数sh=图像宽度; 常数数据=平方图像,sx,sy,sw,sh; //通过角度绑定更新DOM。。。 img.src=数据; } } };
在一次旋转中损失如此之大,以至于在我的约束下,即使这个解决方案也不可信。感觉上有一种方法可以减少工件,但可能没有。例如,如果我只是旋转图像,质量是好的。但旋转后的裁剪不是吗?而且,只要裁剪一个未旋转的图像就可以了?为什么把两者放在一起会如此糟糕,特别是因为旋转和裁剪是在两个不同的画布上完成的?而且,如果图像是正方形,质量也很好。?你有一些css应用在你的图像上吗?在代码片段中,质量对我来说还不错。嗯,我仍然需要保存图像,所以如果它们旋转然后刷新,在大约4次旋转后,图像会变得非常糟糕。不完全是我想在生产代码中输入的。然后保存原始图像和当前转换。不知道你在做什么,我们帮不了你。当你们旋转图像时,你们并没有办法保持图像的原始质量。