Paper.js 子栅格选择了错误的区域

Paper.js Subraster Selecting Wrong Area

我在一个 Paper.js 项目中工作,我们基本上是在进行图像编辑。有一个大光栅。我正在尝试使用 getSubRaster 方法复制图像(光栅)的一部分,然后用户可以四处移动。

加载要编辑的光栅后,调用selectArea注册这些侦听器:

var selectArea = function() {
  if(paper.project != null) {
    var startDragPoint;

    paper.project.layers[0].on('mousedown', function(event) { // TODO should be layer 0 in long run? // Capture start of drag selection
      if(event.event.ctrlKey && event.event.altKey) {
        startDragPoint = new paper.Point(event.point.x + imageWidth/2, (event.point.y + imageHeight/2));
        //topLeftPointOfSelectionRectangleCanvasCoordinates = new paper.Point(event.point.x, event.point.y);
      }
    });
    paper.project.layers[0].on('mouseup', function(event) { // TODO should be layer 0 in long run? // Capture end of drag selection
      if(event.event.ctrlKey && event.event.altKey) {
        var endDragPoint = new paper.Point(event.point.x + imageWidth/2, event.point.y + imageHeight/2);

        // Don't know which corner user started dragging from, aggregate the data we have into the leftmost and topmost points for constructing a rectangle
        var leftmostX;
        if(startDragPoint.x < endDragPoint.x) {
          leftmostX = startDragPoint.x;
        } else {
          leftmostX = endDragPoint.x;
        }
        var width = Math.abs(startDragPoint.x - endDragPoint.x);

        var topmostY;
        if(startDragPoint.y < endDragPoint.y) {
          topmostY = startDragPoint.y;
        } else {
          topmostY = endDragPoint.y;
        }
        var height = Math.abs(startDragPoint.y - endDragPoint.y);

        var boundingRectangle = new paper.Rectangle(leftmostX, topmostY, width, height);
        console.log(boundingRectangle);
        console.log(paper.view.center);
        var selectedArea = raster.getSubRaster(boundingRectangle);

        var selectedAreaAsDataUrl = selectedArea.toDataURL();
        var subImage = new Image(width, height);
        subImage.src = selectedAreaAsDataUrl;

        subImage.onload = function(event) {
          var subRaster = new paper.Raster(subImage);

          // Make movable
          subRaster.onMouseEnter = movableEvents.showSelected;
          subRaster.onMouseDrag = movableEvents.dragItem;
          subRaster.onMouseLeave = movableEvents.hideSelected;
        };        
      }
    });
  }
};

这些方法在正确的时间触发,selection box 似乎大小合适。它确实为我呈现了一个我可以四处移动的新光栅,但光栅的内容不是我 select 编辑的。它们接近于我 selected 但不是我 selected。选择不同的区域似乎不会产生不同的结果。生成的子栅格的内容似乎总是在实际 selection.

的下方和右侧

请注意,当我为边界 selection 矩形构建点时,我会进行一些翻译。这是因为坐标系的不同。我绘制矩形 selection 的坐标系在图像中心有 (0,0),x 向右增加,y 向下增加。但是对于 getSubRaster,我们需要根据文档提供像素坐标,它从图像左上角的 (0,0) 开始,并向右和向下增加。因此,在构建点时,我通过添加 imageWidth/2 和 imageHeight/2` 将点转换为 raster/pixel 坐标。

那么为什么这段代码select发错区了呢?提前致谢。

编辑:

很遗憾,我无法分享我正在处理的图像,因为它是敏感的公司数据。但这里有一些元数据:

我的 canvas 大小因浏览器 window 的大小而异,但这些是我一直在测试的参数。我认为 canvas 尺寸不是特别相关,因为我正在根据图像像素做所有事情。据我所知,当我捕获 event.point.xevent.point.y 时,这些是图像缩放坐标,但来自不同的原点 - 中心而不是左上角。不幸的是,我找不到任何关于此的文档。 观察坐标在sketch.

中是如何工作的

我也一直在研究 sketch to illustrate the problem of this question. To use it, hold Ctrl + Alt and drag a box on the image. This should trigger some logging data and attempt to get a subraster, but I get an operation insecure error, which I think is because of security settings in the image request header. Using the base 64 string instead of the URL doesn't give the security error, but doesn't do anything. Using that string in the sketch produces a super long URL I can't paste here. But to get that you can download the image (or any image) and convert it here,并将其作为 img.src

问题是鼠标事件所有 return 点相对于 canvas 的 0, 0getSubRaster 期望坐标相对于它从中提取的栅格项的 0, 0

调整需要eventpoint - raster.bounds.topLeft。它与图像的宽度或高度没有任何关系。您想要调整事件点,使它们相对于栅格的 0, 0,并且 0, 0raster.bounds.topLeft

当您将事件点调整为图像大小的 1/2 时,会导致事件点偏移不正确。对于蒙娜丽莎的例子,光栅大小(图像大小)是w: 320, h: 491;除以二是 w: 160, h: 245.5。但是图像的 bounds.topLeft(当我 运行 我的素描时)是 x: 252.5, y: 155.5

这是一个显示其工作原理的草图。我添加了一个小的红色方块来突出显示所选区域,以便在完成时更容易进行比较。我也没有包含 toDataURL 逻辑,因为它会产生您提到的安全问题。

给你:Sketch

这是我放入 HTML 文件中的代码;我注意到我放在一起的草图链接到不能完全工作的以前版本的代码。

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

<head>
<meta charset="utf-8">
<title>Rasters</title>
<script src="./vendor/jquery-2.1.3.js"></script>
<script src="./vendor/paper-0.9.25.js"></script>
</head>
<body>
<main>
    <h3>Raster Bug</h3>
    <div>
        <canvas id="canvas"></canvas>
    </div>
    <div id="position">

    </div>
</main>

<script>
 // initialization code
 $(function() {
     // setup paper
     $("#canvas").attr({width: 600, height: 600});
     var canvas = document.getElementById("canvas");
     paper.setup(canvas);

     // show a border to make range of canvas clear
     var border = new paper.Path.Rectangle({
         rectangle: {point: [0, 0], size: paper.view.size},
         strokeColor: 'black',
         strokeWidth: 2
     });

     var tool = new paper.Tool();

     // setup mouse position tracking
     tool.on('mousemove', function(e) {
         $("#position").text("mouse: " + e.point);
     });

     // load the image from a dataURL to avoid CORS issues
     var raster = new paper.Raster(dataURL);
     raster.position = paper.view.center;

     var lt = raster.bounds.topLeft;
     var startDrag, endDrag;

     console.log('rb', raster.bounds);
     console.log('lt', lt);

     // setup mouse handling
     tool.on('mousedown', function(e) {
         startDrag = new paper.Point(e.point);
         console.log('sd', startDrag);
     });
     tool.on('mousedrag', function(e) {
         var show = new paper.Path.Rectangle({
             from: startDrag,
             to: e.point,
             strokeColor: 'red',
             strokeWidth: 1
         });
         show.removeOn({
             drag: true,
             up: true
         });
     });
     tool.on('mouseup', function(e) {
         endDrag = new paper.Point(e.point);
         console.log('ed', endDrag);

         var bounds = new paper.Rectangle({
             from: startDrag.subtract(lt),
             to: endDrag.subtract(lt)
         });
         console.log('bounds', bounds);

         var sub = raster.getSubRaster(bounds);
         sub.bringToFront();

         var subData = sub.toDataURL();
         sub.remove();

         var subRaster = new paper.Raster(subData);
         subRaster.position = paper.view.center;

     });

 });

 var dataURL = ; // insert data or real URL here

 </script>
</body>
</html>