栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

Java Swing:如何获取JFrame像素的颜色

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java Swing:如何获取JFrame像素的颜色

我想说(希望这样做会带来更好的性能),也许,如果您愿意采用这种

Image
方法,则最好创建一个尺寸为1x1像素的图像,然后转换其创建的图形以匹配所请求的图形点。并将此图像重新用于相同
Component
(甚至
GraphicsConfiguration
)的后续采样。

我通过创建以下方法进行了一些性能测试:

  1. 所谓的一种方法,
    getColorAtClipped
    它设置的创建剪辑
    Graphics
    的的
    Image
    要绘制所以并不是所有操作都有。
  2. 一种称为的方法
    getColorAtRelocation
    ,该方法将组件的位置临时设置在需要采样的位置,然后(实际上使其更快)创建尺寸为1x1的图像并在其上绘制父对象。尽管此方法对于Swing而言并不是真正的线程安全方法,因为它需要设置
    Component
    来回的位置。它还要求
    printAll
    父级
    Container
    ,这意味着
    Component
    要绘制更多。
  3. 然后调用一种方法
    getColorAtTranslation
    ,该方法创建一个1x1图像并转换其
    Graphics
    实例,以便所需的位置实际上将绘制在(0,0)处,这是图像中真正的唯一像素。事实证明,对于这前三种方法,该方法是最快的。
  4. 那么,为什么不为以后的样本重用相同的资源呢?…这导致我进入最终方法:一个包含所有参与样本的必需资源的类:
    ComponentColorSampler
    在以下代码中调用的一个类

测试代码:

本节中的代码用于测试上述方法的性能。如果不正确,请在评论中让我知道,但是请注意,我对每种方法进行了大约300万次采样,以期避免附带的延迟。测试方法的每百万个样本中,我会打印一些时间,然后重新启动该过程以测试另外一百万个,最多3个。

import java.awt.Color;import java.awt.Component;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.Point;import java.awt.image.BufferedImage;import java.lang.reflect.InvocationTargetException;import java.util.Objects;import java.util.function.IntBinaryOperator;import java.util.function.Supplier;import javax.swing.Jframe;import javax.swing.JPanel;import javax.swing.SwingUtilities;public class Main {    public static Color getColorAtClipped(final Component comp, final Point p) {        final BufferedImage bimg = comp.getGraphicsConfiguration().createCompatibleImage(comp.getWidth(), comp.getHeight());        final Graphics2D g2d = (Graphics2D) bimg.createGraphics();        g2d.setClip(p.x, p.y, 1, 1);        comp.printAll(g2d);        g2d.dispose();        final Color c = new Color(bimg.getRGB(p.x, p.y), true);        bimg.flush();        return c;    }    public static Color getColorAtRelocation(final Component comp, final Point p) {        final Point loc = comp.getLocation();        final BufferedImage bimg = comp.getGraphicsConfiguration().createCompatibleImage(1, 1);        comp.setLocation(loc.x - p.x, loc.y - p.y);        final Graphics2D g2d = (Graphics2D) bimg.createGraphics();        //g2d.setClip(0, 0, 1, 1);        comp.getParent().printAll(g2d);        comp.setLocation(loc);        g2d.dispose();        final Color c = new Color(bimg.getRGB(0, 0), true);        bimg.flush();        return c;    }    public static Color getColorAtTranslation(final Component comp, final Point p) {        final BufferedImage bimg = comp.getGraphicsConfiguration().createCompatibleImage(1, 1);        final Graphics2D g2d = (Graphics2D) bimg.createGraphics();        g2d.translate(-p.x, -p.y);        //g2d.setClip(0, 0, 1, 1);        comp.printAll(g2d);        g2d.dispose();        final Color c = new Color(bimg.getRGB(0, 0), true);        bimg.flush();        return c;    }    public static class ComponentColorSampler<C extends Component> implements AutoCloseable, IntBinaryOperator, Supplier<C> {        private final C comp;        private final BufferedImage bimg;        private final Graphics2D g2d;        private int x, y;        public ComponentColorSampler(final C comp) { this.comp = Objects.requireNonNull(comp); bimg = comp.getGraphicsConfiguration().createCompatibleImage(1, 1); g2d = bimg.createGraphics(); //g2d.setClip(0, 0, 1, 1); x = y = 0;        }        @Override        public C get() { return comp;        }        @Override        public int applyAsInt(final int x, final int y) { g2d.clearRect(0, 0, 1, 1); g2d.translate(this.x - x, this.y - y); this.x = x; this.y = y; comp.printAll(g2d); return bimg.getRGB(0, 0);        }        public Color sample(final int x, final int y) { return new Color(applyAsInt(x, y), true);        }        @Override        public void close() { g2d.dispose(); bimg.flush();        }    }    public static class DrawPanel extends JPanel {        private final int x, y;        private Color c;        public DrawPanel(final int x, final int y) { this.x = x; this.y = y; c = Color.BLUE;        }        @Override        protected void paintComponent(final Graphics g) { super.paintComponent(g); g.setColor(c); g.fillRect(x, y, 1, 1);        }        public void setColor(final Color c) { this.c = Objects.requireNonNull(c); paintImmediately(0, 0, getWidth(), getHeight()); //Not sure yet. repaint(); //Just to be sure now.        }    }    //@SuppressWarnings("SleepWhileInLoop")    public static boolean checkValid(final DrawPanel dp, final Supplier<Color> sampler) throws InterruptedException, InvocationTargetException {        for (final Color c: new Color[]{Color.BLUE, Color.RED, Color.BLACK, Color.WHITE, Color.BLACK, Color.CYAN}) { SwingUtilities.invokeAndWait(() -> dp.setColor(c)); Thread.sleep(250); //Let it some time to change (not sure if needed). if (!Objects.equals(c, sampler.get()))     return false;        }        return true;    }    public static long checkTime(final Supplier<Color> sampler) {        final long start = System.currentTimeMillis();        for (int i = 0; i < 1000000; ++i) sampler.get();        return System.currentTimeMillis() - start;    }    public static void main(final String[] args) throws InterruptedException, InvocationTargetException {        final Point p = new Point(100, 100);        final DrawPanel contents = new DrawPanel(p.x, p.y);        contents.setPreferredSize(new Dimension(200, 200));        final Jframe frame = new Jframe("Printed!");        frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);        frame.getContentPane().add(contents);        frame.pack();        frame.setLocationRelativeTo(null);        frame.setResizable(false);        frame.setVisible(true);        final ComponentColorSampler<Component> sampler = new ComponentColorSampler<>(contents);        final Supplier<Color> clipped = () -> getColorAtClipped(contents, p),        relocation = () -> getColorAtRelocation(contents, p),        translation = () -> getColorAtTranslation(contents, p),        samplerSampler = () -> sampler.sample(p.x, p.y);        System.out.println("#### Validity checks...");        for (int i = 0; i < 3; ++i) { System.out.println("Batch " + (i + 1) + ':'); System.out.println("> Clipped: " + checkValid(contents, clipped) + '.'); System.out.println("> Relocation: " + checkValid(contents, relocation) + '.'); System.out.println("> Translation: " + checkValid(contents, translation) + '.'); System.out.println("> Sampler: " + checkValid(contents, samplerSampler) + '.');        }        System.out.println("#### Timings...");        for (int i = 0; i < 3; ++i) { System.out.println("Batch " + (i + 1) + ':'); System.out.println("> Clipped: " + checkTime(clipped) + "ms."); System.out.println("> Relocation: " + checkTime(relocation) + "ms."); System.out.println("> Translation: " + checkTime(translation) + "ms."); System.out.println("> Sampler: " + checkTime(samplerSampler) + "ms.");        }        System.out.println("#### Done.");    }}

结果:

程序输出:

#### Validity checks...Batch 1:> Clipped: true.> Relocation: true.> Translation: true.> Sampler: true.Batch 2:> Clipped: true.> Relocation: true.> Translation: true.> Sampler: true.Batch 3:> Clipped: true.> Relocation: true.> Translation: true.> Sampler: true.#### Timings...Batch 1:> Clipped: 34668ms.> Relocation: 22737ms.> Translation: 5416ms.> Sampler: 1152ms.Batch 2:> Clipped: 38521ms.> Relocation: 22805ms.> Translation: 5451ms.> Sampler: 1156ms.Batch 3:> Clipped: 38275ms.> Relocation: 22864ms.> Translation: 5415ms.> Sampler: 1163ms.#### Done.

因此,对于一百万个样本,第一种方法大约需要37秒,第二种方法大约需要22秒,第三种方法大约需要5秒,最后一种方法恰好超过1秒(对于一百万个样本)。

ComponentColorSampler
在这些测试中最快的实现也是如此(每毫秒约865个样本),并且可以在任何测试上运行
Component
。有效性检查只是为了稍微验证所采样的颜色是否具有正确的值。

注意 :这些测试不是Swing /线程安全的,但是指出了正确使用它们(例如,在事件调度线程上执行采样)的性能。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/402036.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号