【问题标题】:Resize image in Java without losing transparency在 Java 中调整图像大小而不会失去透明度
【发布时间】:2012-09-15 03:39:02
【问题描述】:

我想在不丢失透明度的情况下调整图像(jpg、png、gif)的大小。

我想在调整大小后将调整大小的版本保存到磁盘。

我搜索了很多,但我只找到了失去透明度并将透明空间填充为黑色的解决方案......

我正在寻找可以完成这项工作的 sn-p 或库 :)

【问题讨论】:

  • 您只是想调整它们的大小以供显示(相对容易)还是在磁盘上创建第二个调整大小的图像(困难得多)?
  • 我想在磁盘上创建第二个调整大小的图像。例如上传的网站头像。
  • OK - 首先关注透明度。请注意,J2SE 没有编写动画 GIF 的简单方法,而且 PNG 根本不提供动画。
  • 我应该打开一个新问题还是编辑这个问题? png 提供动画:apng en.wikipedia.org/wiki/APNG (例如在 Firefox 中支持)
  • 我想编辑这个。并且“便携式网络图形 (PNG) 规范的非官方扩展 不是 PNG。至少,在 J2SE 理解的任何意义上都没有。

标签: java image resize png gif


【解决方案1】:

经过研究,我发现只有将缓冲区图像保留为 BufferedImage 而不将其转换为 ImageIcon 时,才能调整其大小

我这样解决问题:

public class NewJFrame extends javax.swing.JFrame {

/**
 * Creates new form NewJFrame
 */
public NewJFrame()  {
    try {
        initComponents();
        BufferedImage c = ImageIO.read(new File("60_Personnel.png"));
        JLabel lblMains = new JLabel( new ImageIcon(c));
        this.add(lblMains);                                       //add real size
        this.add(new JLabel(new ImageIcon((resize(c, 150)))));    //add converting image
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    } catch (IOException ex) {
        Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
    }

}

public static BufferedImage resize(Object img, int percent) {
    BufferedImage buff = (BufferedImage) img;
    return resize(buff, buff.getWidth() * percent / 100, buff.getWidth() * percent / 100);
}

public static BufferedImage resize(BufferedImage img, int newW, int newH) {
    Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
    BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = dimg.createGraphics();
    g2d.drawImage(tmp, 0, 0, null);
    g2d.dispose();
    return dimg;
}

}

【讨论】:

【解决方案2】:

改成这样:

public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics2D = resizedImage.createGraphics();
        graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
        graphics2D.dispose();
        return resizedImage;
    }

到这里:

public static BufferedImage resizeImage(BufferedImage originalImage, int targetWidth, int targetHeight) {
        BufferedImage resizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D graphics2D = resizedImage.createGraphics();
        graphics2D.drawImage(originalImage, 0, 0, targetWidth, targetHeight, null);
        graphics2D.dispose();
        return resizedImage;
    }

您基本上将“BufferedImage.TYPE_INT_RGB”更改为“BufferedImage.TYPE_INT_ARGB”

【讨论】:

    【解决方案3】:

    这就是我解决问题的方法:

    public static BufferedImage convertRGBAToIndexed(BufferedImage src) {
        BufferedImage dest = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_INDEXED);
        Graphics g = dest.getGraphics();
        g.setColor(new Color(231, 20, 189));
        g.fillRect(0, 0, dest.getWidth(), dest.getHeight());
        dest = makeTransparent(dest, 0, 0);
        dest.createGraphics().drawImage(src, 0, 0, null);
        return dest;
    }
    
    public static BufferedImage makeTransparent(BufferedImage image, int x, int y) {
        ColorModel cm = image.getColorModel();
        if (!(cm instanceof IndexColorModel))
            return image; // sorry...
        IndexColorModel icm = (IndexColorModel) cm;
        WritableRaster raster = image.getRaster();
        int pixel = raster.getSample(x, y, 0);
        int size = icm.getMapSize();
        byte[] reds = new byte[size];
        byte[] greens = new byte[size];
        byte[] blues = new byte[size];
        icm.getReds(reds);
        icm.getGreens(greens);
        icm.getBlues(blues);
        IndexColorModel icm2 = new IndexColorModel(8, size, reds, greens, blues, pixel);
        return new BufferedImage(icm2, raster, image.isAlphaPremultiplied(), null);
    }
    
    public static Dimension getScaledDimension(Dimension imgSize, Dimension boundary) {
        int original_width = imgSize.width;
        int original_height = imgSize.height;
        int bound_width = boundary.width;
        int bound_height = boundary.height;
        int new_width = 0;
        int new_height = 0;
    
        if (original_width > original_height) {
            new_width = bound_width;
            new_height = (new_width*original_height)/original_width;
        } else {
            new_height = bound_height;
            new_width = (new_height*original_width)/original_height;
        }
    
        return new Dimension(new_width, new_height);
    }
    
    public static void resizeImage(File original_image, File resized_image, int IMG_SIZE) {
        try {
            BufferedImage originalImage = ImageIO.read(original_image);
    
            String extension = Files.getFileExtension(original_image.getName());
    
            int type = extension.equals("gif") || (originalImage.getType() == 0) ? BufferedImage.TYPE_INT_ARGB : originalImage.getType();
    
            Dimension new_dim = getScaledDimension(new Dimension(originalImage.getWidth(), originalImage.getHeight()), new Dimension(IMG_SIZE,IMG_SIZE));
    
            BufferedImage resizedImage = new BufferedImage((int) new_dim.getWidth(), (int) new_dim.getHeight(), type);
            Graphics2D g = resizedImage.createGraphics();
            g.drawImage(originalImage, 0, 0, (int) new_dim.getWidth(), (int) new_dim.getHeight(), null);
            g.dispose();            
    
            if (!extension.equals("gif")) {
                ImageIO.write(resizedImage, extension, resized_image);
            } else {
                // Gif Transparence workarround
                ImageIO.write(convertRGBAToIndexed(resizedImage), "gif", resized_image);
            }
    
        } catch (IOException e) {
            Utils.log("resizeImage", e.getMessage());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 2013-06-03
      • 2013-01-02
      • 2011-03-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多