How to improve the performance of g.drawImage() method for resizing images

后端 未结 12 1507
面向向阳花
面向向阳花 2020-11-27 11:16

I have an application where users are able to upload pictures in albums but naturally the uploaded images need to be resized so there are also thumbs available and the shown

12条回答
  •  清歌不尽
    2020-11-27 12:01

    The fastest way to scale an image in java without loosing image quality is to use Bilinear scaling. Bilinear is only good if you scale the image by 50% at a time because of the way it works. The following code is from 'Filthy rich clients' by Chet Haase. He explains multiple techniques in the book, but this one has the highest performance to quality trade-off.

    It supports all types of BufferedImages so don't worry about compatability. It also lets java2D hardware accelerate your image because the calculations are done by Java2D. Don't worry if you don't understand that last part. The most important thing is that this is the fastest way to do it.

    public static BufferedImage getFasterScaledInstance(BufferedImage img, int targetWidth, int targetHeight, boolean progressiveBilinear)
    {
        int type = (img.getTransparency() == Transparency.OPAQUE) ? 
                BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage ret = (BufferedImage) img;
        BufferedImage scratchImage = null;
        Graphics2D g2 = null;
        int w, h;
        int prevW = ret.getWidth();
        int prevH = ret.getHeight();
        if(progressiveBilinear) {
            w = img.getWidth();
            h = img.getHeight();
        }else{
            w = targetWidth;
            h = targetHeight;
        }
        do {
            if (progressiveBilinear && w > targetWidth) {
                w /= 2;
                if(w < targetWidth) {
                    w = targetWidth;
                }
            }
    
            if (progressiveBilinear && h > targetHeight) {
                h /= 2;
                if (h < targetHeight) {
                    h = targetHeight;
                }
            }
    
            if(scratchImage == null) {
                scratchImage = new BufferedImage(w, h, type);
                g2 = scratchImage.createGraphics();
            }
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2.drawImage(ret, 0, 0, w, h, 0, 0, prevW, prevH, null);
            prevW = w;
            prevH = h;
            ret = scratchImage;
        } while (w != targetWidth || h != targetHeight);
    
        if (g2 != null) {
            g2.dispose();
        }
    
        if (targetWidth != ret.getWidth() || targetHeight != ret.getHeight()) {
            scratchImage = new BufferedImage(targetWidth, targetHeight, type);
            g2 = scratchImage.createGraphics();
            g2.drawImage(ret, 0, 0, null);
            g2.dispose();
            ret = scratchImage;
        }
        System.out.println("ret is "+ret);
        return ret;
    }
    

提交回复
热议问题