gpt4 book ai didi

java - SWT 在外壳上绘制一个 "transparent"矩形

转载 作者:搜寻专家 更新时间:2023-11-01 02:51:55 25 4
gpt4 key购买 nike

我想创建一个“选择区域”工具。此工具应允许使用鼠标在屏幕上绘制一个矩形区域。

我使用全屏、半透明、变暗的 swt Shell 作为我的背景,我在其上绘制了一个白色矩形来表示所选区域。

我的问题是我没有找到刷新矩形区域的有效方法。直到现在我都使用了 redraw 方法但是视觉效果非常丑陋,甚至认为我试图只重绘他需要的区域:

    public ManualScreenAreaSelector(final Display display) {
shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP);
shell.setBounds(display.getClientArea());
// shell.setFullScreen(true);
shell.setAlpha(180);
shell.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
shell.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
}

@Override
public void mouseMove(final MouseEvent e) {
if (editionMode) {
// retrieve the rectangular area corresponding to mouse selection
final Rectangle r = makeRectangleFromSelection(clickCoordinates, new Point(e.x, e.y));
// make the ugly 'tint' effect
shell.redraw();

GC gc = new GC(shell);
gc.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_WHITE));
gc.setAlpha(150);

gc.fillRectangle(r.x, r.y, r.width, r.height);

gc.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_BLACK));
gc.fillRectangle(0, 0, r.x, r.y);
gc.fillRectangle(0, 1080 - r.y, r.x, 1080 - r.y);
gc.dispose();

lastX = e.x;
lastY = e.y;
}
}

@Override
public void mouseDown(final MouseEvent e) {
// Right click = reset selection
if (e.button == 3) {
shell.redraw();
selectedArea = null;
if (editionMode) {
editionMode = false;
shell.removeMouseMoveListener(ManualScreenAreaSelector.this);
}
} else if (e.button == 1) {
// left-click enter edition mode
// Reset previous selection
selectedArea = null;
editionMode = true;
clickCoordinates = new Point(e.x, e.y);
lastX = e.x;
lastY = e.y;
shell.addMouseMoveListener(ManualScreenAreaSelector.this);
}
}

@Override
public void mouseUp(final MouseEvent e) {
// left click, only if edition was set
if ((e.button == 1) && editionMode) {
editionMode = false;
shell.removeMouseMoveListener(ManualScreenAreaSelector.this);
selectedArea = makeRectangleFromSelection(clickCoordinates, new Point(e.x, e.y));
shell.dispose();
}
}

所以我想知道在 SWT 中是否存在更有效的解决方案,而不必使用重绘方法。

actual result


编辑我使用了 3 张图像来进行选择:

  • 首先是屏幕图像(屏幕截图)
  • 第二个是屏幕图像+alpha混合暗色矩形
  • 第三个是缓冲区,我在其上绘制 alpha 混合图像 + 从屏幕截图图像复制的矩形。

性能是可以接受的,因为只有一个 alpha 混合操作(对于第二张图像)。

只有一个问题仍然存在,当我第一次使用 shell 的图形控件绘制 shell 时,alpha 混合图像未用作 shell 背景,发送鼠标事件时其他一切正常:

public ManualScreenAreaSelector(final Display display) {

screenWidth = display.getClientArea().width;
screenHeight = display.getClientArea().height;
// create a new Image of the screen
backGround = new Image(display, display.getBounds());
GC gc = new GC(display);
gc.copyArea(backGround, 0, 0);
gc.dispose();

// Copy background image and add alpha blended effect
aplhaBackGround = new Image(backGround.getDevice(), backGround.getImageData());
GC alphaGC = new GC(aplhaBackGround);
alphaGC.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
alphaGC.setAlpha(200);
alphaGC.fillRectangle(0, 0, screenWidth, screenHeight);
alphaGC.dispose();

// create the shell
shell = new Shell(display, SWT.NO_TRIM | SWT.ON_TOP | SWT.NO_BACKGROUND);
shell.setBounds(display.getClientArea());

// get shell graphics control
shellGraphics = new GC(shell);
// set the shell image to screen image <-- does nothing
shellGraphics.drawImage(aplhaBackGround, 0, 0);

// Image for the shell
bufferImage = new Image(shell.getDisplay(), shell.getBounds());

shell.print(shellGraphics);
}
public void mouseMove(final MouseEvent e) {
if (editionMode) {
// Get selected area
final Rectangle selectedArea = makeRectangleFromSelection(clickCoordinates, new Point(
e.x, e.y));
// Copy alpha blended background into the buffer
GC gc1 = new GC(aplhaBackGround);
gc1.copyArea(bufferImage, 0, 0);
gc1.dispose();
// Paint "normal" background over selected area
GC gc2 = new GC(bufferImage);
gc2.drawImage(backGround, selectedArea.x, selectedArea.y, selectedArea.width,
selectedArea.height, selectedArea.x, selectedArea.y, selectedArea.width,
selectedArea.height);

// draw the painted image on the shell
shellGraphics.drawImage(bufferImage, 0, 0);
gc2.dispose();
}
}

最佳答案

试试这个方法:

  • 代替 shell.redraw();,调用一次 shell.print(gc) 并将 GC 附加到图像缓冲区。这为您提供了外壳的图像。

  • 获取 SWT 的 OpenGL 扩展或 jogl .将图像放在背景中并为选区创建一个 3D 矩形。使用 OpenGL 进行 alpha 操作和合成。

原因是 SWT 中的 alpha 操作速度很慢,这通常需要使用 CPU 来完成。您的显卡每秒可以执行数百次相同的操作,而不会出汗。

关于java - SWT 在外壳上绘制一个 "transparent"矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9586112/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com