我正在尝试使用Canvas
方法将鼠标光标周围的区域从Image
复制到gc.copyarea
。之后我想将该图像绘制到按下鼠标1秒后出现的复合图像上。
以下是我的代码:
在我的画布的paintControl
方法中,我将区域复制到图像:
img = new Image(display, 40, 40);
gc.copyArea(img, mousePosition.x-20, mousePosition.y-20);
在我的复合的paintControl
方法中,我绘制了该图像:
if (img != null) {
gc.drawImage(img, 0, 0);
}
我遇到的问题是,实际上只有很小一部分区域被复制并涂在复合材料上。在40x40像素区域中,复合材料中只能看到左下角10x20像素区域的区域。
实施例:
光标位于compisite左上角的旁边。只有光标周围区域的一小部分被涂在compisite上
问题:如何从画布复制区域并将其正确地绘制到另一个复合材料上?我的代码中我做错了什么?
答案 0 :(得分:1)
经过一些反复试验,我设法得到了一些可以接近你想要的东西。
public class CopyArea {
public static void main( String[] args ) {
CopyArea copyArea = new CopyArea();
copyArea.create();
copyArea.run();
}
private Display display;
private Image sourceImage;
private Point canvasSize;
private Shell shell;
private Canvas source;
private Canvas destination;
private Point snippetOrigin;
private Image snippet;
CopyArea() {
display = new Display();
sourceImage = new Image( display, getClass().getResourceAsStream( "mona-lisa.jpeg" ) );
canvasSize = new Point( sourceImage.getBounds().width, sourceImage.getBounds().height );
shell = new Shell( display );
source = new Canvas( shell, SWT.NONE );
destination = new Canvas( shell, SWT.NONE );
}
void create() {
shell.setLayout( new RowLayout() );
source.setLayoutData( new RowData( canvasSize ) );
source.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
event.gc.drawImage( sourceImage, 0, 0 );
if( snippetOrigin != null ) {
snippet = new Image( display, 40, 40 );
event.gc.copyArea( snippet, snippetOrigin.x, snippetOrigin.y );
destination.redraw();
snippetOrigin = null;
}
}
} );
source.addMouseListener( new MouseAdapter() {
@Override
public void mouseDown( MouseEvent event ) {
snippetOrigin = new Point( event.x, event.y );
source.redraw();
}
} );
destination.setLayoutData( new RowData( canvasSize ) );
destination.addPaintListener( new PaintListener() {
@Override
public void paintControl( PaintEvent event ) {
event.gc.setBackground( display.getSystemColor( SWT.COLOR_WHITE ) );
event.gc.fillRectangle( event.gc.getClipping() );
if( snippet != null ) {
event.gc.drawImage( snippet, 0, 0 );
}
}
} );
}
void run() {
shell.pack();
shell.open();
while( !shell.isDisposed() ) {
if( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}
}
sourceImage
只是绘图代码的占位符。 source
Canvas侦听鼠标按下事件,然后将其客户端的40x40片段绘制到destination
Canvas。请注意,我在两种情况下都使用Canvas,但Canvas和Composite也应该可以使用。
以下是它的工作原理:鼠标监听器将鼠标位置存储到snippetOrigin
并触发source
的重绘。 source
的绘画听众会根据请求(snippetOrigin != null
)对其刚刚绘制的内容进行部分屏幕截图,然后强制destination
重新绘制自己。 destination
简单的绘画监听器会绘制snippet
图像(如果有)。
代码deos尚未正确剪辑复制的图像。如果您在source
画布的右下角按下鼠标,也会复制一些shell修剪。
为简洁起见,代码在重用之前不会丢弃snippet
图像(并且可能有其他泄漏)。
如果您拥有绘制相当于source
Canvas的绘图代码,我宁愿重构它以便可以绘制任意部分,然后使用适当的参数调用代码以在{{1}上绘制小部件。
答案 1 :(得分:0)
试试这个代码,示例获取画布区域的副本并粘贴到对象中
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(10, 10, 50, 50);
function copy() {
var imgData = ctx.getImageData(10, 10, 50, 50);
ctx.putImageData(imgData, 10, 70);
}
在这种情况下,副本被粘贴到画布目的地作为原点
试试这个参考
https://www.w3schools.com/tags/canvas_getimagedata.asp
这是 API 参考
https://developer.mozilla.org/es/docs/Web/API/CanvasRenderingContext2D/getImageData