如何将缓冲图像转换为图像,反之亦然?

其实我正在研究图像编辑软件,现在我想转换缓冲图像,即:

BufferedImage buffer = ImageIO.read(new File(file)); 

到图像,即格式如下:

  Image image = ImageIO.read(new File(file)); 

有可能吗? 如果是,那怎么样?

BufferedImage 是一个(n)图像,因此您在第二行中执行的隐式转换可以直接编译。 如果你知道一个Image真的是一个BufferedImage,你必须像这样明确地转换它:

 Image image = ImageIO.read(new File(file)); BufferedImage buffered = (BufferedImage) image; 

因为BufferedImage扩展了Image,所以它可以放在Image容器中。 但是,任何Image都可以适合那里,包括那些不是BufferedImage的Image,因此如果类型不匹配,你可能会在运行时获得ClassCastException,因为BufferedImage除非扩展BufferedImage,否则不能保存任何其他类型。

示例:假设您有一个想要缩放的“图像”,您可能需要一个bufferedImage,并且可能只是从“Image”对象开始。 所以我认为这是有效的… AVATAR_SIZE是我们希望图像的目标宽度:

 Image imgData = image.getScaledInstance(Constants.AVATAR_SIZE, -1, Image.SCALE_SMOOTH); BufferedImage bufferedImage = new BufferedImage(imgData.getWidth(null), imgData.getHeight(null), BufferedImage.TYPE_INT_RGB); bufferedImage.getGraphics().drawImage(imgData, 0, 0, null); 

BufferedImage是Image的子类。 您无需进行任何转换。

您可以尝试使用所做的更改保存(或写入)缓冲图像 ,然后将其作为图像打开。

编辑:

 try { // Retrieve Image BufferedImage buffer = ImageIO.read(new File("old.png"));; // Here you can rotate your image as you want (making your magic) File outputfile = new File("saved.png"); ImageIO.write(buffer, "png", outputfile); // Write the Buffered Image into an output file Image image = ImageIO.read(new File("saved.png")); // Opening again as an Image } catch (IOException e) { ... } 

只是一个信息:让我们都记住, Image类实际上是一个抽象类,并且使用BufferedImage引用它的变量只存储或返回任何Object的内存地址。

此外,静态java.awt.image.imageIOread()方法返回一个BufferedImage对象,因此毫无疑问,在该对象上使用运算符/表达式instanceof BufferedImage将返回true

事实上,作为抽象, Image类有这样的方法签名:

  1. public abstract Graphics getGraphics()
  2. public abstract ImageProducer getSource()

等等。

我强调,实际的Image变量只保存具体Image-subclass对象的内存地址,几乎就像C,C ++,Ada等中的指针一样。

如果您使用这些语言介绍或高级,还有Java接口实例,如Runnablejavax.sound.Clip ,AWT的Shape等等。 注意Image有: public abstract Image getScaledInstance(...) – 你明白了。 (当然,2D图形编程中的缩放可以与resize互换,因此需要精度)。

但在一个不可能的情况下,这里ImageIO方法返回! (instanceof BufferedImage) ! (instanceof BufferedImage)只是创建一个新的BufferedImage对象, ImgObjNotInstncfBufImg包含一个构造函数参数的ImgObjNotInstncfBufImg。 然后,在(理性)将在代码的逻辑中操纵它。

无论如何,仿射变换类适用于将形状和图像转换为缩放,旋转,重定位等forms,因此我建议您研究使用“仿射变换”。

请注意,您可以操纵此类图像栅格中的实际像素 – 这是另一种必须从技术词汇表中引用的技术2D图形术语 – 在图像缓冲区的类型中,可能需要以Java方式进行二进制blitwise操作的精通技巧将单个颜色属性存储在32字节的紧凑型中 – 每个7位用于alpha和RGB值。

我怀疑你会用它来分层图像。 所以,最后,理性的是你只使用抽象Image引用BufferedImage ,如果你的Image对象还不是BufferedImage ,那么你可以用这个相关但非BufferedImage实例制作一个图像。无需担心任何转换,铸造,自动装箱等等; 操纵BufferedImage实际上意味着还要操纵它所指向的基础图像数据承载对象。

好的,完成了; 我想我肯定已经解决了你可能认为你面临的僵局。 正如我所说的java中的抽象类以及接口,非常类似于其他语言中称为指针的低级,更接近硬件的运算符。

正确的方法是使用SwingFXUtils.toFXImage(bufferedImage,null)将BufferedImage转换为JavaFX Image实例,使用SwingFXUtils.fromFXImage(image,null)进行逆操作。

可选地,第二参数可以是WritableImage以避免进一步的对象分配。