在StackOverflow上已存在类似此链接的问题,并且接受的答案是"强制转换":
Image image = ImageIO.read(new File(file));
BufferedImage buffered = (BufferedImage) image;
Run Code Online (Sandbox Code Playgroud)
在我的程序中,我尝试:
final float FACTOR = 4f;
BufferedImage img = ImageIO.read(new File("graphic.png"));
int scaleX = (int) (img.getWidth() * FACTOR);
int scaleY = (int) (img.getHeight() * FACTOR);
Image image = img.getScaledInstance(scaleX, scaleY, Image.SCALE_SMOOTH);
BufferedImage buffered = (BufferedImage) image;
Run Code Online (Sandbox Code Playgroud)
不幸的是我得到了运行时错误:
sun.awt.image.ToolkitImage无法强制转换为java.awt.image.BufferedImage
显然铸造不起作用.
问题是:将Image转换为BufferedImage的正确方法是什么(或有没有)?
列出您最喜欢的堆分析工具(例如jprofiler,jmap,...).让我们为每个答案保留一个工具,并列出每个工具的优缺点.
一种尝试的方法是使用TexturePaint和g.fillRect()绘制图像.然而,这需要您在每次绘制图像时创建一个新的TexturePaint和Rectangle2D对象,这是不理想的 - 并且无论如何都没有帮助.
当我使用时g.drawImage(BufferedImage,...),旋转的图像看起来模糊/柔和.
我熟悉RenderingHints和双缓冲(我认为这就是我正在做的事情),我发现很难相信你不能轻易有效地在Java中旋转产生尖锐结果的图像.
使用代码TexturePaint看起来像这样.
Grahics2D g2d = (Graphics2D)g;
g2d.setPaint(new TexturePaint(bufferedImage, new Rectangle2D.Float(0,0,50,50)));
g2d.fillRect(0,0,50,50);
Run Code Online (Sandbox Code Playgroud)
我正在用AffineTransform一把牌旋转成一个风扇.什么是快速绘制好看图像的最佳方法?
这是一个截图:
9是清脆的,但其余的卡肯定不那么尖锐.
问题可能出在我创建每张卡片图像并将其存储在数组中时.
这就是我现在正在做的事情:
// i from 0 to 52, card codes.
...
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
BufferedImage img = gc.createCompatibleImage(86, 126, Transparency.TRANSLUCENT);
Graphics2D g = img.createGraphics();
setRenderingHints(g);
g.drawImage(shadow, 0, 0, 86, 126, null);
g.drawImage(white, 3, 3, 80, 120, null);
g.drawImage(suit, 3, 3, 80, …Run Code Online (Sandbox Code Playgroud) 任务: 我有一些图像,我缩小它们,并将它们连接到一个图像.但是我对实现有一点问题:
具体问题: 我想调整大小/缩放BufferedImage.getScaledInstance方法返回一个Image对象,但我无法将其强制转换为BufferedImage:
Exception in thread "main" java.lang.ClassCastException: sun.awt.image.ToolkitImage cannot be cast to java.awt.image.BufferedImage
Run Code Online (Sandbox Code Playgroud)
(我不知道为什么它是ToolkitImage而不是Image ...)
我找到了解决方案:
Image tmp = bi.getScaledInstance(SMALL_SIZE, SMALL_SIZE, BufferedImage.SCALE_FAST);
BufferedImage buffered = new BufferedImage(SMALL_SIZE,SMALL_SIZE,BufferedImage.TYPE_INT_RGB);
buffered.getGraphics().drawImage(tmp, 0, 0, null);
Run Code Online (Sandbox Code Playgroud)
但它很慢,我认为应该有更好的方法来做到这一点.
我需要BufferedImage,因为我必须让像素加入小图像.
有更好的(更好/更快)的方式吗?
编辑: 如果我首先将Image转换为ToolkitImage,它有一个getBufferedImage()方法.但它总是返回null.你知道为什么吗?
我正在使用Batik来处理SVG图像.有没有办法从SVG文件中获取java.awt.image.BufferedImage?
我知道有转码器,我可以将SVG转码为例如PNG,然后用ImageIO.read()加载PNG但我不想拥有临时文件.
我有一个Swing表单,在JScrollPane中有一个自定义表(它只是一个JPanel,而不是JTable子类),我试图让它打印出来.如果我只是将整个框架发送到打印机,滚动窗格会切断,如果我将框架的大小调整为滚动窗格内容的大小,某种内部屏障会阻止JFrame变得超过1100像素高.
另一种方法是创建对话框的内容窗格而不将其附加到根JFrame,因为JPanel的大小在这种情况下不受限制.但是为了让组件自行调整并调整到适当的大小,我似乎需要使面板可显示,这意味着至少将它添加到JFrame并调用JFrame.pack(),但同样,1100像素限制回来了.
这是我打印组件的代码:
public static void print(final Component comp) {
final float SCALE = .5f;
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(new Printable() {
public int print(Graphics g, PageFormat pf, int page)
throws PrinterException
{
if (page * pf.getImageableHeight() >= SCALE * comp.getHeight())
return NO_SUCH_PAGE;
((Graphics2D)g).translate(pf.getImageableX(), pf.getImageableY()
- page * pf.getImageableHeight());
((Graphics2D)g).scale(SCALE, SCALE);
comp.printAll(g);
return PAGE_EXISTS;
}
});
if (job.printDialog())
try { job.print(); }
catch (PrinterException ex) {}
}
Run Code Online (Sandbox Code Playgroud)
如果我这样做,组件的大小为零:
JPanel c = createPanel(); // This JPanel has a JScrollPane in it …Run Code Online (Sandbox Code Playgroud) 我已经看过这个问题,但它似乎没有真正回答我的问题.我有一个图像文件,可能是任何分辨率.我需要以BufferedImage特定分辨率将该图像加载到对象中(例如,对于此示例,800x800).我知道Image类可以getScaledInstance()用来将图像缩放到一个新的大小,但我无法弄清楚如何将它恢复到一个新的大小BufferedImage.有没有一种简单的方法可以将缓冲图像缩放到特定大小?
注意 II不希望按特定因子缩放图像,我想拍摄图像并制作特定尺寸.
我正在写一个测试应用程序.要为图像设置Alpha,我使用paintComponent方法.观看下一个片段......
public class TestImage extends JLabel{
public void paintComponent( Graphics g ) {
super.paintComponent( g );
Graphics2D g2d=(Graphics2D)g;
g2d.drawImage(this.bImage, rop, 0, 0);
}
public void setRescaleOp(RescaleOp rop){this.rop=rop;}
}
Run Code Online (Sandbox Code Playgroud)
如你看到的,
g2d.drawImage(this.bImage,rop,0,0);
不允许设置宽度和高度,就像我使用g.drawImage(bImage,0,0,width,height,null);
所以问题是......在这种情况下如何设置bImage的宽度和高度?
任何有用的评论表示赞赏
安德鲁
我使用这段代码将Image绘制到Graphics组件中.如果图像足够大,它应该将图像调整到可用的最大空间:
// getWidth() = component width, image.getWidth() = image width
double w = getWidth() * 1.0 / image.getWidth();
double h = getHeight() * 1.0 / image.getHeight();
if (w < 1 || h < 1) {
double d = Math.min(Math.min(w, h), 1);
g.drawImage(bi.getScaledInstance((int) (d * image.getWidth()), (int) (d * image.getHeight()), Image.SCALE_REPLICATE), 0, 0, null);
} else {
g.drawImage(bi, 0, 0, null);
}
Run Code Online (Sandbox Code Playgroud)
代码工作,图像正确缩放.但不幸的是,当图像缩放时,图像的亮度也会在图形上发生变化!
有谁知道这可能来自哪里?我附加了屏幕的缩放(第一个)和未缩放版本.
我希望有人可以帮助我!
干杯! 塞巴斯蒂安

编辑:请参阅此答案的评论以回答此问题.TLDR:瓶颈是缩放图像,但分析显示这是ImageIcon构造函数中的一个问题.
$ java -version
Picked up _JAVA_OPTIONS: -Dswing.aatext=true -Dawt.useSystemAAFontSettings=on
java version "1.7.0_45"
OpenJDK Runtime Environment (IcedTea 2.4.3) (ArchLinux build 7.u45_2.4.3-1-x86_64)
OpenJDK 64-Bit Server VM (build 24.45-b08, mixed mode)
Run Code Online (Sandbox Code Playgroud)
我的应用程序在启动时加载1,380个图标.加载代码如下所示.使用SSD磁盘,ImageIcon构造函数调用实际上比磁盘读取更昂贵(尽管磁盘读取可能使用一些缓存...)
加载图标需要5.4s,在ImageIcon构造函数中花费3.2s.
有没有办法加快ImageIcon构建或使用其他东西?
private ImageIcon setIcon(LogicalIcon iconInfo, int size) {
ImageIcon icon = iconImages.get(iconInfo.getIconName());
if(icon == null) {
BufferedImage image = null;
try {
image = ImageIO.read(getBestPreviewIcon(iconInfo).getFile());
icon = new ImageIcon(ImageUtils.scaleDownTo(image, new Dimension(size, size)));
iconImages.put(iconInfo.getIconName(), icon);
} catch (IOException e) {
// FIXME: Add a "Missing Image" icon
e.printStackTrace();
}
}
setIcon(icon); …Run Code Online (Sandbox Code Playgroud) 我有很多图像由我的数码相机拍摄,分辨率非常高,分辨率为3000*4000,需要大量的硬盘空间,我用Photoshop打开每张图像并重新调整尺寸,但分辨率很小,但需要很多时间和精力
我认为我可以编写简单的程序打开图像文件夹并读取每个文件并获取它的宽度和高度,如果它非常高,则更改它并用小图像覆盖图像.