Fabricjs:使用角度属性裁剪图像

问题描述 投票:0回答:2

我通过对象方法toDataURL(不是画布)使用左、上、宽度和高度等参数裁剪图像。效果很好,但我没有 知道当图像的角度属性不等于0时我该怎么办? 我尝试调用 setAngle=0 -> setCoords() -> toDataURL() 恢复 angle <-- it works but not so well and i think this workflow is't good.

cropImage: ->
  sLeft = @glob.data.selectArea.left
  sTop = @glob.data.selectArea.top
  sAngle = @glob.data.selectArea.angle

  @glob.data.selected.setAngle(0)
  @glob.data.selected.setCoords()
  @glob.data.cropPicture.setAngle(0)
  @glob.data.cropPicture.setCoords()

  cropParams = {
    width:  @glob.data.selectArea.getWidth()
    height: @glob.data.selectArea.getHeight()
    left:   @glob.data.selectArea.getLeft() - @glob.data.cropPicture.getLeft()
    top:    @glob.data.selectArea.getTop() - @glob.data.cropPicture.getTop()
  }
  ...
  croppedDataUrl = @glob.data.cropPicture.toDataURL(cropParams)
  fabric.Image.fromURL(croppedDataUrl, (img) =>
    img.left = sLeft
    img.top = sTop
    img.angle = sAngle
    @glob.data.canvas.add(img)
  ...
javascript fabricjs angle rect
2个回答
0
投票

我的解决方案:

cropImage: ->
    # origin image
    originWidth  = @glob.cropPicture.getWidth()
    originHeight = @glob.cropPicture.getHeight()
    originLeft   = @glob.cropPicture.left
    originTop    = @glob.cropPicture.top

    # coordinates of the center of origin image
    ctxLeft = - originWidth / 2 + @glob.cropPicture.strokeWidth
    ctxTop = - originHeight / 2 + @glob.cropPicture.strokeWidth

    # crop mask
    width  = @glob.selectArea.getWidth()
    height = @glob.selectArea.getHeight()
    angle  = @glob.selectArea.getAngle()
    left   = @glob.selectArea.left
    top    = @glob.selectArea.top

    cropLeft = left - originLeft
    cropTop = top - originTop

    @glob.cropPicture.clipTo = (ctx) =>
      ctx.save()
      ctx.translate(ctxLeft, ctxTop)
      ctx.rect(cropLeft, cropTop, width, height)
      ctx.restore()

    @glob.cropPicture.angle = 0
    @glob.cropPicture.setCoords()
    cropData = @glob.cropPicture.toDataURL()
    @glob.cropPicture.angle = angle
    @glob.cropPicture.setCoords()

    fabric.Image.fromURL(cropData, (img1) =>
      params = {
        width: width
        height: height
        left: cropLeft
        top: cropTop
      }
      fabric.Image.fromURL(img1.toDataURL(params), (img2) =>
        @glob.canvas.add img2
      )
    )

    @glob.canvas.renderAll()

0
投票

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fabric.js Practice</title>
    <style>
        #crop {
            display: none;
        }
    </style>
</head>

<body>
    <canvas id="c"></canvas>
    <button id="crop">Crop</button>
    <button id="startCrop" style="border: 1px solid #000000">Mark Crop Area</button>
    <br />
    <canvas style="visibility: hidden" id="canvas_crop"></canvas>
    <script src="https://unpkg.com/[email protected]/dist/fabric.min.js"></script>
    <script>
        let currentImage;
        const canvas = initCnvas();
        canvas.preserveObjectStacking = true;

        addImage(canvas);
        createMaskForCrop(canvas);
        crop(canvas);

        function initCnvas() {
            return new fabric.Canvas("c", {
                width: 1200,
                height: 600,
                strokeWidth: 5,
                stroke: "rgba(100,200,200,0.5)",
            });
        }

        function addImage(canvas) {
            fabric.Image.fromURL('https://via.placeholder.com/400', (img) => {
                canvas.add(img);
                canvas.centerObject(img);
                canvas.setActiveObject(img);
                currentImage = img;
                canvas.renderAll();
            }, { crossOrigin: 'anonymous' })
        }

        function createMaskForCrop(canvas) {
            document.querySelector("#startCrop").addEventListener("click", function () {
                addSelectionRect();
                canvas.setActiveObject(selectionRect);
                canvas.renderAll();
                document.querySelector("#crop").style.display = "block";
            });
        }

        function addSelectionRect() {
            selectionRect = new fabric.Rect({
                left: currentImage.left,
                top: currentImage.top,
                width: currentImage.width,
                height: currentImage.height,
                fill: 'rgb(178, 178, 178, 0.4)',
                transparentCorners: false,
                cornerColor: 'rgb(178, 178, 178, 0.8)',
                strokeWidth: 1,
                cornerStrokeColor: 'black',
                borderColor: 'black',
                borderDashArray: [5, 5],
                cornerStyle: 'circle',
                cornerSize: 8,
                fillRule: 'Croping',
                lockMovementX: true,
                lockMovementY: true,
                scaleX: currentImage.scaleX,
                scaleY: currentImage.scaleY,
                angle: currentImage.angle
            });
            canvas.add(selectionRect);
        }

        function crop(canvas) {
            document.querySelector("#crop").addEventListener("click", function (event) {
                document.querySelector("button#crop").style.display = "none";

                let angle = currentImage.angle;
                const group = new fabric.Group([currentImage, selectionRect]);
                group.rotate(360 - angle);
                group.ungroupOnCanvas();
                canvas.renderAll();
                let cropX = (selectionRect.left - currentImage.left)/currentImage.scaleX;
                let cropY = (selectionRect.top - currentImage.top)/currentImage.scaleY;
                let cropWidth = selectionRect.getScaledWidth()/currentImage.scaleX;
                let cropHeight = selectionRect.getScaledHeight()/currentImage.scaleY;

                currentImage.set({
                    top: currentImage.top + cropY * currentImage.scaleY,
                    left: currentImage.left + cropX * currentImage.scaleX,
                    cropX: cropX,
                    cropY: cropY,
                    width: cropWidth,
                    height: cropHeight
                });
                canvas.remove(selectionRect);
                canvas.remove(group);
                canvas.setActiveObject(currentImage);
                currentImage.rotate(angle);
                canvas.renderAll();
            });
        }
    </script>
</body>

</html>

使用fabric js裁剪图像包括图像角度

© www.soinside.com 2019 - 2024. All rights reserved.