【问题标题】:How to convert buffered image to image and vice-versa?如何将缓冲图像转换为图像,反之亦然?
【发布时间】:2012-02-03 16:42:19
【问题描述】:

实际上我正在开发一个图像编辑软件,现在我想转换缓冲图像,即:

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

到图像,即格式如下:

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

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

【问题讨论】:

    标签: java image bufferedimage


    【解决方案1】:

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

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

    因为 BufferedImage 扩展了 Image,所以它可以放入 Image 容器中。但是,任何图像都可以放在那里,包括不是 BufferedImage 的图像,因此如果类型不匹配,您可能会在运行时收到 ClassCastException,因为 BufferedImage 不能保存任何其他类型,除非它扩展了 BufferedImage。

    【讨论】:

    • 实际上我正在尝试旋转我的图像,我可以通过使用以下形式的图像来做到这一点: Image image = ImageIO.read(new File(file));但是当给出缓冲图像时我不知道该怎么做??
    • 对 BufferedImage 说“图像”就像称猫为动物——仅仅因为它是猫并不意味着它不是动物。 BufferedImage 是一个 Image 但它不是任何其他类型的 Image - 一般而言,任何需要 Image 的东西都可以与 BufferedImage 一起使用。
    【解决方案2】:

    示例:假设您有一个想要缩放的“图像”,您可能需要一个缓冲图像,并且可能会从“图像”对象开始。所以我认为这很有效...... 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);
    

    【讨论】:

      【解决方案3】:

      BufferedImageImage 的子类。您无需进行任何转换。

      【讨论】:

      • 实际上我正在尝试旋转我的图像,我可以通过使用以下形式的图像来做到这一点: Image image = ImageIO.read(new File(file));但是当给出缓冲图像时我不知道该怎么做??
      【解决方案4】:

      您可以尝试 saving (or writing) the Buffered 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) {
          ...
      }
      

      【讨论】:

      • 我不明白..我没有得到你... :(
      【解决方案5】:

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

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

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

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

      等等。

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

      如果您对这些语言以及 Runnablejavax.sound.Clip、AWT 的 Shape 等 Java 接口实例进行了介绍或进阶。请注意Image 有:public abstract Image getScaledInstance(...) - 你明白了。 (当然,2D 图形编程中的缩放可以与调整大小互换,这需要精度)。

      但是在不可能的情况下,ImageIO 方法返回 ! (instanceof BufferedImage) 只需创建一个新的 BufferedImage 对象,并将此 ImgObjNotInstncfBufImg 传递给它的构造函数参数之一。然后, at (rational) 将在您的代码逻辑中操作它。

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

      请注意,您可以在此类图像的 Raster 中操作实际像素 - 以及必须从技术词汇表中引用的另一个技术 2D 图形行话 - 这可能需要 Java 二进制 blitwise 操作方式的熟练技能,在类型以 32 字节压缩存储单个颜色属性的图像缓冲区 - alpha 和 RGB 值各 7 位。

      我怀疑你会在分层图像中使用它。所以,最后,合理的是你只用抽象图像引用BufferedImage,如果你的Image对象还不是BufferedImage,那么你可以用这个相关的-但是-non-BufferedImage-instance,无需担心任何转换、转换、自动装箱或其他任何事情;操作 BufferedImage 实际上也意味着操作它指向的底层根 Image 数据承载对象。

      好的,完成;我想我当然提取并分裂了你可能认为你面临的僵局。正如我所说的,java 中的抽象类和接口在很大程度上等同于其他语言中称为指针的低级、更接近硬件的运算符。

      【讨论】:

      • 老实说,我在那里失去了你几次。感觉就像你的这段话:“但是在一个不可能的情况下,当 ImageIO 方法返回时!(实例 BufferedImage)只需创建一个新的 BufferedImage 对象,并将这个 ImgObjNotInstncfBufImg 传递给它的构造函数参数之一。然后,在(理性)将操纵这个在你的代码逻辑中。”有洞的答案,但我不太明白。您已经解释了很多,但对实际答案的反应非常快......
      【解决方案6】:

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

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

      【讨论】:

      • 这个问题是老问题,早于 JavaFX 2,所以它指的是 java.awt.Image 而不是 java.scene.image.Image。但是,这个答案仍然很有用,因为如果有人遇到这个问题并且真的想将 BufferedImage 转换为 JavaFX 图像,这确实是这样做的方法。
      • 我的错,我只是想知道,因为所有解决方案都写入磁盘,这在性能方面是不可取的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2013-03-26
      相关资源
      最近更新 更多