2015-10-29 71 views
3

我在一个Paper.js项目中工作,我们主要进行图像编辑。有一个大型栅格。我试图使用getSubRaster方法复制用户可以移动的图像部分(光栅)。Paper.js Subraster选择错误的区域

编辑光栅被加载后,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; 
     };   
     } 
    }); 
    } 
}; 

的方法是在正确的时间触发,选择框似乎是正确的大小。它的确为我提供了一个新的光栅,可以移动,但光栅的内容并不是我选择的内容。他们接近我选择的内容,但不是我选择的内容。选择不同的区域似乎不会产生不同的结果。生成的子流程的内容似乎总是在实际选择的右侧。

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

那么为什么这段代码选择了错误的区域呢?提前致谢。

编辑:

可惜我不能分享我用,因为它是敏感的公司数据的工作形象。但这里是一些元数据:

  • 图片宽度:4250个像素
  • 图像高度:5500个像素
  • 画布宽度:591个像素
  • 帆布高度:766个像素

我的画布大小因浏览器窗口的大小而异,但这些都是我一直在测试的参数。我不认为画布尺寸特别相关,因为我在图像像素方面做了所有事情。据我所知,当我捕获event.point.xevent.point.y时,这些是图像缩放坐标,但来自不同的原点 - 中心而不是左上角。不幸的是,我找不到任何文件。 观察这个坐标在这个sketch中的工作方式。

我也一直致力于sketch来说明这个问题的问题。要使用它,请按住Ctrl + Alt并拖动图像上的一个框。这应该会触发一些日志记录数据并尝试获取子数据库,但是我得到一个操作不安全错误,我认为这是由于图像请求标头中的安全设置。使用基本64字符串而不是URL不会导致安全错误,但不会执行任何操作。在草图中使用该字符串会生成超长URL,我无法在此处进行粘贴。但为了得到那你可以下载image(或任何图像)并将其转换为here,并将其作为img.src

+0

您能否提供图片,画布大小以及如何翻译坐标?这里没有足够的信息来说明问题是什么。我唯一能想到的就是图像比画布大,所以它的bounds.x和bounds.y是负数,但这取决于更多的信息。 – bmacnaughton

+0

@bmacnaughton谢谢,看看编辑。我希望这是有帮助的。让我知道我还能做些什么来使事情更清晰。 –

回答

2

问题是鼠标事件相对于画布的0, 0的所有返回点。并且getSubRaster预计坐标是相对于它从中提取的栅格项目的0, 0

调整需要为eventpoint - raster.bounds.topLeft。它与图像的宽度或高度没有任何关系。您希望调整事件点,使它们相对于栅格的0, 00, 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> 
+0

嘿,也许你可以帮助解决这个问题,它是从Sketch中构建的。 http://stackoverflow.com/questions/33676618/paper-js-subraster-added-behind-rectangle-instead-of-in-front –