本文介绍了如何增加JPictureBox的绘图速度大的图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JPictureBox从java.awt.Component中看到code扩展这里。但它仅适用以及在没有图像拉伸。特别是对于大画面,它极大地减慢程序。如何增加JPictureBox的绘图速度为大型形象?

  @覆盖
公共无效漆(图形G){
    super.paint(G);    INT X = 0;
    INT Y = 0;
    INT W = 0;
    INT H = 0;
    如果(形象!= NULL){
        开关(sizeMode){
            案例AUTO_SIZE:
            属于正常现象:
                W = image.getWidth();
                H = image.getHeight();
                打破;
            案例CENTER_IMAGE:
                W = image.getWidth();
                H = image.getHeight();
                X =(的getWidth() - w)的/ 2;
                Y =(的getHeight() - H)/ 2;
                打破;
            案例STRETCH_IMAGE:
                W =的getWidth();
                H =的getHeight();
                打破;
            案例ZOOM:
                W =(INT)Math.round(image.getWidth()* zoomFactor);
                H =(INT)Math.round(image.getHeight()* zoomFactor);
                打破;
            案例FIT_BOTH:
                如果(image.getWidth()> image.getHeight()){
                    W =的getWidth();
                    H =(int)的(重量/ getAR());                    如果(h取代;的getHeight()){
                        H =的getHeight();
                        W =(int)的(H * getAR());
                    }
                }其他{
                    H =的getHeight();
                    W =(int)的(H * getAR());                    如果(并且R w的getWidth()){
                        W =的getWidth();
                        H =(int)的(重量/ getAR());
                    }
                }
                打破;
            案例FIT_WIDTH:
                W =的getWidth();
                H =(int)的(重量/ getAR());
                打破;
            案例FIT_HEIGHT:
                H =的getHeight();
                W =(int)的(H * getAR());
                打破;
        }        Graphics2D的G2D =(Graphics2D的)克;
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.drawImage(图像,X,Y,W,H,这一点);
    }否则如果(errorIcon!= NULL){
        W = errorIcon.getIconWidth();
        H = errorIcon.getIconHeight();
        X =(的getWidth() - w)的/ 2;
        Y =(的getHeight() - H)/ 2;
        errorIcon.paintIcon(此,G,X,Y);
    }
}


解决方案

基本上,你要的图像的缩放关装载到一个后台线程,脱屑非常耗时,而且你不希望的范围内做事件指派线程。

这则提出了其他几个问题。你不希望将图像缩放,直到你真的要和你真的只想知道最新的结果。

而不是试图扩展在每一个变化的图像,你可以设置你重置每次一小,单曲重复计时器要做出改变。这将巩固多个大小调整要求降低到尽可能少的请求越好。本例中使用 javax.swing.Timer中的设置为短125毫秒的延迟。因此,它会等待请求之间至少有125毫秒的变化实际上触发更新之前。

其次,它使用了的ExecutorService 设置了一个单独的线程。这为我们提供了手段,以企图取消任何pre-现有业务,因为我们不希望有结果和开始我们的最新要求。

接下来,实际的缩放操作采用两步比例,首先,它会尝试做一个快速,低质量的规模,可以在屏幕上迅速付诸然后执行较慢的,高质量的规模是在某个时候更新在未来...

 进口java.awt.Dimension中;
进口java.awt.EventQueue中;
进口java.awt.Graphics;
进口java.awt.Graphics2D中;
进口java.awt.Image中;
进口java.awt.Rectangle中;
进口java.awt.RenderingHints中;
进口java.awt.Transparency;
进口java.awt.event.ActionEvent中;
进口java.awt.event.ActionListener;
进口java.awt.event.KeyEvent中;
进口java.awt.image.BufferedImage中;
进口的java.io.File;
进口java.io.IOException异常;
进口的java.util.ArrayList;
进口的java.util.List;
进口java.util.concurrent.Callable;
进口java.util.concurrent.ExecutorService中;
进口java.util.concurrent.Executors;
进口java.util.concurrent.Future;
进口javax.imageio.ImageIO中;
进口javax.swing.AbstractAction中;
进口javax.swing.ActionMap中;
进口javax.swing.InputMap中;
进口javax.swing.JFrame中;
进口javax.swing.JPanel中;
进口javax.swing.JScrollPane中;
进口javax.swing.KeyStroke;
进口javax.swing.Scrollable;
进口javax.swing.SwingUtilities中;
进口javax.swing.Timer中;
进口javax.swing.UIManager中;
进口javax.swing.UnsupportedLookAndFeelException;公共类的测试{    公共静态无效的主要(字串[] args){
        新的测试();
    }    公开测试(){
        EventQueue.invokeLater(新的Runnable(){
            @覆盖
            公共无效的run(){
                尝试{
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                }赶上(ClassNotFoundException的| InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException前){
                    ex.printStackTrace();
                }                JFrame的帧=新的JFrame(测试);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(新JScrollPane的(新TestPane()));
                frame.pack();
                frame.setLocationRelativeTo(NULL);
                frame.setVisible(真);
            }
        });
    }    公共类TestPane继承JPanel实现滚动{        私人的BufferedImage掌握;
        私人影像缩放;
        私人双重变焦= 1D;
        私人ExecutorService的服务;
        私人列表<&未来GT; scaleTa​​sks;
        私人最终计时器zoomTimer;        公共TestPane(){
            scaleTa​​sks =新的ArrayList<>(5);
            服务= Executors.newSingleThreadExecutor();
            尝试{
                主= ImageIO.read(新文件(有些像一些地方));
                缩放=主;
            }赶上(IOException异常前){
                ex.printStackTrace();
            }
            zoomTimer =新的Timer(125,新的ActionListener(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    的System.out.println(更新缩放到+ getZoom());
                    updateToZoomFactor(getZoom());
                }
            });
            zoomTimer.setRepeats(假);            IM的InputMap = getInputMap中(WHEN_IN_FOCUSED_WINDOW);
            ActionMap中上午= getActionMap();            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0),加);
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0),负);            am.put(加,新AbstractAction(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    双重变焦= getZoom()+ 0.1;
                    setZoom(缩放);
                }
            });
            am.put(减,新AbstractAction(){
                @覆盖
                公共无效的actionPerformed(ActionEvent的五){
                    双重变焦= getZoom() - 0.1;
                    setZoom(缩放);
                }
            });        }        @覆盖
        公共尺寸的get preferredSize(){
            返回缩放== NULL
                            ?新的Dimension(master.getWidth(),master.getHeight())
                            新维度(scaled.getWidth(本),scaled.getHeight(本));
        }        公众的BufferedImage getMaster(){
            返回主;
        }        公共无效setZoom(double值){
            如果(价值< 0.1){
                值= 0.1;
            }否则如果(值大于2){
                值= 2D;
            }
            如果(值!=缩放){
                变焦=价值;
                zoomTimer.restart();
            }
        }        公共双getZoom(){
            返回变焦;
        }        @覆盖
        保护无效paintComponent(图形G){
            super.paintComponent方法(G);
            如果(缩放!= NULL){
                Graphics2D的G2D =(Graphics2D的)g.create();
                INT X =(的getWidth() - scaled.getWidth(本))/ 2;
                INT Y =(的getHeight() - scaled.getHeight(本))/ 2;
                g2d.drawImage(缩放,X,Y,这一点);
                g2d.dispose();
            }
        }        保护无效setScaledResult(最终图像的图像){
            SwingUtilities.invokeLater(Runnable的新(){
                @覆盖
                公共无效的run(){
                    缩放=图像;
                    无效();
                    重新验证();
                    重绘();
                }
            });
        }        保护无效updateToZoomFactor(双变焦){
            未来[] =任务scaleTa​​sks.toArray(新未来[scaleTa​​sks.size()]);
            对于(未来任务:任务){
                如果(!task.isCancelled()){
                    task.cancel(真);
                }其他{
                    scaleTa​​sks.remove(任务);
                }
            }
            service.submit(新RescaleTa​​sk(变焦));
        }        @覆盖
        公共尺寸的get preferredScrollableViewportSize(){
            返回新尺寸(400,400);
        }        @覆盖
        公众诠释getScrollableUnitIncrement(矩形的visibleRect,诠释取向,诠释方向){
            返回128;
        }        @覆盖
        公众诠释getScrollableBlockIncrement(矩形的visibleRect,诠释取向,诠释方向){
            返回128;
        }        @覆盖
        公共布尔getScrollableTracksViewportWidth(){
            返回false;
        }        @覆盖
        公共布尔getScrollableTracksViewportHeight(){
            返回false;
        }        保护类RescaleTa​​sk实现可调用的<图像> {            私人双重变焦;            保护RescaleTa​​sk(双变焦){
                this.zoom =缩放;
            }            @覆盖
            公众形象()调用抛出异常{
                如果(变焦== 1){
                    缩放= getMaster();
                }其他{
                    INT宽度=(INT)(getMaster()的getWidth()*变焦。);
                    INT高度=(INT)(getMaster()的getHeight()*变焦。);
                    。图像缩放= getMaster()getScaledInstance((INT)宽度(INT)的高度,Image.SCALE_FAST);
                    如果(!Thread.currentThread()。isInterrupted()){
                        setScaledResult(缩放);                        如果(缩放< 1){
                            缩放= getScaledDownInstance(getMaster(),(INT)的宽度,(i​​nt)的高度);
                        }其他{
                            缩放= getScaledUpInstance(getMaster(),(INT)的宽度,(i​​nt)的高度);
                        }                        如果(!Thread.currentThread()。isInterrupted()){
                            setScaledResult(缩放);
                        }其他{
                            的System.out.println(有人在质量规模中断);
                        }                    }其他{
                        的System.out.println(被快速大规模期间中断);
                    }
                }
                返回比例;
            }            受保护的BufferedImage getScaledDownInstance(BufferedImage的IMG,
                            INT targetWidth,
                            INT targetHeight){                整型=(img.getTransparency()==为Transparency.OPAQUE)
                                ? BufferedImage.TYPE_INT_RGB:BufferedImage.TYPE_INT_ARGB;                RET的BufferedImage =(BufferedImage的)IMG;                如果(targetHeight大于0 || targetWidth大于0){                    INT W = img.getWidth();
                    INT H = img.getHeight();                    做{                        的System.out.println(W +×+ H + - >中+ targetWidth +×+ targetHeight);                        如果(并且R w targetWidth){
                            重量/ = 2;
                            如果(W< targetWidth){
                                W = targetWidth;
                            }
                        }                        如果(H> targetHeight){
                            的h / = 2;
                            如果(H< targetHeight){
                                H = targetHeight;
                            }
                        }                        BufferedImage的TMP =新的BufferedImage(Math.max(W,1),Math.max(H,1)型);
                        G2的Graphics2D = tmp.createGraphics();
                        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                        g2.drawImage(保留,0,0,W,H,NULL);
                        g2.dispose();                        RET = tmp目录;                    }而(W = targetWidth || H = targetHeight!);                }其他{                    RET =新的BufferedImage(1,1,类型);                }                返回RET;            }            受保护的BufferedImage getScaledUpInstance(BufferedImage的IMG,
                            INT targetWidth,
                            INT targetHeight){                整型= BufferedImage.TYPE_INT_ARGB;                RET的BufferedImage =(BufferedImage的)IMG;
                INT W = img.getWidth();
                INT H = img.getHeight();                做{                    如果(W< targetWidth){
                        W * = 2;
                        如果(并且R w targetWidth){
                            W = targetWidth;
                        }
                    }                    如果(H< targetHeight){
                        H * = 2;
                        如果(H> targetHeight){
                            H = targetHeight;
                        }
                    }// createCompatibleImage(W,H,类型)
                    BufferedImage的TMP =新的BufferedImage(W,H,类型);
                    G2的Graphics2D = tmp.createGraphics();
                    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                    g2.drawImage(保留,0,0,W,H,NULL);
                    g2.dispose();                    RET = tmp目录;
                    TMP = NULL;                }而(W = targetWidth || H = targetHeight!);                返回RET;            }        }    }}

注:这是对杀人一点,但是演示了一些关键的思路

一个其他的东西,可能会帮助是将图像转换为的GraphicsDevice ,例如...

兼容的颜色模型

 主= ImageIO.read(新文件(有些像一些地方));
            GraphicsDevice的GD = GraphicsEnvironment.getLocalGraphicsEnvironment()getDefaultScreenDevice()。
            的GraphicsConfiguration GC = gd.getDefaultConfiguration();
            的BufferedImage兼容= gc.createCompatibleImage(master.getWidth(),master.getHeight(),Transparency.TRANSLUCENT);
            Graphics2D的G2D = compatiable.createGraphics();
            g2d.drawImage(主,0,0,这一点);
            g2d.dispose();
            主=兼容;

I have a JPictureBox extends from a java.awt.Component see code here http://pastebin.com/SAJc6Sht. But it only works well when there is no image stretching. Especially for the big picture, it slows program dramatically. How to increase drawing speed of JPictureBox for large image?

@Override
public void paint(Graphics g) {    
    super.paint(g);

    int x = 0;
    int y = 0;
    int w = 0;
    int h = 0;
    if (image != null) {
        switch (sizeMode) {
            case AUTO_SIZE:
            case NORMAL:
                w = image.getWidth();
                h = image.getHeight();
                break;
            case CENTER_IMAGE:
                w = image.getWidth();
                h = image.getHeight();
                x = (getWidth() - w) / 2;
                y = (getHeight() - h) / 2;
                break;
            case STRETCH_IMAGE:
                w = getWidth();
                h = getHeight();
                break;
            case ZOOM:
                w = (int) Math.round(image.getWidth() * zoomFactor);
                h = (int) Math.round(image.getHeight() * zoomFactor);
                break;
            case FIT_BOTH:
                if (image.getWidth() > image.getHeight()) {
                    w = getWidth();
                    h = (int) (w / getAR());

                    if (h > getHeight()) {
                        h = getHeight();
                        w = (int) (h * getAR());
                    }
                } else {
                    h = getHeight();
                    w = (int) (h * getAR());

                    if (w > getWidth()) {
                        w = getWidth();
                        h = (int) (w / getAR());
                    }
                }
                break;
            case FIT_WIDTH:
                w = getWidth();
                h = (int) (w / getAR());
                break;
            case FIT_HEIGHT:
                h = getHeight();
                w = (int) (h * getAR());
                break;
        }

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
        g2d.drawImage(image, x, y, w, h, this);
    } else if (errorIcon != null) {
        w = errorIcon.getIconWidth();
        h = errorIcon.getIconHeight();
        x = (getWidth() - w) / 2;
        y = (getHeight() - h) / 2;
        errorIcon.paintIcon(this, g, x, y);
    }
}
解决方案

Basically, you want to off load the scaling of the image to a background thread, scaling is time consuming and you don't want to do within the context of the Event Dispatching Thread.

This then raises a few more issues. You don't want to scale the image until you really have to to and you really only want the latest result.

Instead of trying to scale the image on EVERY change, you can setup a small, single repeat timer which you reset each time you want to make a change. This will consolidate the multiple resize requests down to as few requests as possible. This example uses a javax.swing.Timer set to a short 125 millisecond delay. So it will wait at least 125 milliseconds between requests for a change before actually triggering the update.

Next, it uses a ExecutorService set up with a single thread. This provides us with the means to "attempt" to cancel any pre-existing operations, as we don't want there result and start our latest request.

Next, the actual scaling operation employs a two step scale, first, it tries to do a fast, low quality scale which can be put on the screen quickly and then performs a slower, high quality scale which is updated at some time in the future...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.Scrollable;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(new TestPane()));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements Scrollable {

        private BufferedImage master;
        private Image scaled;
        private double zoom = 1d;
        private ExecutorService service;
        private List<Future> scaleTasks;
        private final Timer zoomTimer;

        public TestPane() {
            scaleTasks = new ArrayList<>(5);
            service = Executors.newSingleThreadExecutor();
            try {
                master = ImageIO.read(new File("Some image some where"));
                scaled = master;
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            zoomTimer = new Timer(125, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Update Zoom to " + getZoom());
                    updateToZoomFactor(getZoom());
                }
            });
            zoomTimer.setRepeats(false);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "plus");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "minus");

            am.put("plus", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    double zoom = getZoom() + 0.1;
                    setZoom(zoom);
                }
            });
            am.put("minus", new AbstractAction() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    double zoom = getZoom() - 0.1;
                    setZoom(zoom);
                }
            });

        }

        @Override
        public Dimension getPreferredSize() {
            return scaled == null
                            ? new Dimension(master.getWidth(), master.getHeight())
                            : new Dimension(scaled.getWidth(this), scaled.getHeight(this));
        }

        public BufferedImage getMaster() {
            return master;
        }

        public void setZoom(double value) {
            if (value < 0.1) {
                value = 0.1;
            } else if (value > 2) {
                value = 2d;
            }
            if (value != zoom) {
                zoom = value;
                zoomTimer.restart();
            }
        }

        public double getZoom() {
            return zoom;
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (scaled != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - scaled.getWidth(this)) / 2;
                int y = (getHeight() - scaled.getHeight(this)) / 2;
                g2d.drawImage(scaled, x, y, this);
                g2d.dispose();
            }
        }

        protected void setScaledResult(final Image image) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    scaled = image;
                    invalidate();
                    revalidate();
                    repaint();
                }
            });
        }

        protected void updateToZoomFactor(double zoom) {
            Future[] tasks = scaleTasks.toArray(new Future[scaleTasks.size()]);
            for (Future task : tasks) {
                if (!task.isCancelled()) {
                    task.cancel(true);
                } else {
                    scaleTasks.remove(task);
                }
            }
            service.submit(new RescaleTask(zoom));
        }

        @Override
        public Dimension getPreferredScrollableViewportSize() {
            return new Dimension(400, 400);
        }

        @Override
        public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 128;
        }

        @Override
        public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
            return 128;
        }

        @Override
        public boolean getScrollableTracksViewportWidth() {
            return false;
        }

        @Override
        public boolean getScrollableTracksViewportHeight() {
            return false;
        }

        protected class RescaleTask implements Callable<Image> {

            private double zoom;

            protected RescaleTask(double zoom) {
                this.zoom = zoom;
            }

            @Override
            public Image call() throws Exception {
                if (zoom == 1) {
                    scaled = getMaster();
                } else {
                    int width = (int) (getMaster().getWidth() * zoom);
                    int height = (int) (getMaster().getHeight() * zoom);
                    Image scaled = getMaster().getScaledInstance((int) width, (int) height, Image.SCALE_FAST);
                    if (!Thread.currentThread().isInterrupted()) {
                        setScaledResult(scaled);

                        if (zoom < 1) {
                            scaled = getScaledDownInstance(getMaster(), (int) width, (int) height);
                        } else {
                            scaled = getScaledUpInstance(getMaster(), (int) width, (int) height);
                        }

                        if (!Thread.currentThread().isInterrupted()) {
                            setScaledResult(scaled);
                        } else {
                            System.out.println("Was interrupted during quality scale");
                        }

                    } else {
                        System.out.println("Was interrupted during fast scale");
                    }
                }
                return scaled;
            }

            protected BufferedImage getScaledDownInstance(BufferedImage img,
                            int targetWidth,
                            int targetHeight) {

                int type = (img.getTransparency() == Transparency.OPAQUE)
                                ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

                BufferedImage ret = (BufferedImage) img;

                if (targetHeight > 0 || targetWidth > 0) {

                    int w = img.getWidth();
                    int h = img.getHeight();

                    do {

                        System.out.println(w + "x" + h + " -> " + targetWidth + "x" + targetHeight);

                        if (w > targetWidth) {
                            w /= 2;
                            if (w < targetWidth) {
                                w = targetWidth;
                            }
                        }

                        if (h > targetHeight) {
                            h /= 2;
                            if (h < targetHeight) {
                                h = targetHeight;
                            }
                        }

                        BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
                        Graphics2D g2 = tmp.createGraphics();
                        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                        g2.drawImage(ret, 0, 0, w, h, null);
                        g2.dispose();

                        ret = tmp;

                    } while (w != targetWidth || h != targetHeight);

                } else {

                    ret = new BufferedImage(1, 1, type);

                }

                return ret;

            }

            protected BufferedImage getScaledUpInstance(BufferedImage img,
                            int targetWidth,
                            int targetHeight) {

                int type = BufferedImage.TYPE_INT_ARGB;

                BufferedImage ret = (BufferedImage) img;
                int w = img.getWidth();
                int h = img.getHeight();

                do {

                    if (w < targetWidth) {
                        w *= 2;
                        if (w > targetWidth) {
                            w = targetWidth;
                        }
                    }

                    if (h < targetHeight) {
                        h *= 2;
                        if (h > targetHeight) {
                            h = targetHeight;
                        }
                    }

//          createCompatibleImage(w, h, type)
                    BufferedImage tmp = new BufferedImage(w, h, type);
                    Graphics2D g2 = tmp.createGraphics();
                    g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                    g2.drawImage(ret, 0, 0, w, h, null);
                    g2.dispose();

                    ret = tmp;
                    tmp = null;

                } while (w != targetWidth || h != targetHeight);

                return ret;

            }

        }

    }

}

nb: This is little over kill, but demonstrates some key ideas

One of the other things that might help is to convert the image to a compatible color model for the GraphicsDevice, for example...

            master = ImageIO.read(new File("Some image some where"));
            GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
            GraphicsConfiguration gc = gd.getDefaultConfiguration();
            BufferedImage compatible = gc.createCompatibleImage(master.getWidth(), master.getHeight(), Transparency.TRANSLUCENT);
            Graphics2D g2d = compatiable.createGraphics();
            g2d.drawImage(master, 0, 0, this);
            g2d.dispose();
            master = compatible;

这篇关于如何增加JPictureBox的绘图速度大的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 05:02