BufferedImage.getGraphics().drawImage() 改变像素值

2024-04-13

(这是一个后续previous https://stackoverflow.com/questions/23707736/strange-bufferedimage-behaviour-with-4bits-palette问题)

标准推荐的改造方式BufferedImage从一种类型转换为另一种类型,或者进行复制,就是使用getGraphics().drawImage() (example https://stackoverflow.com/questions/8864275/how-to-clone-image)。令我惊讶的是,我发现这个过程不会使像素值保持不变,即使源图像和目标图像都属于同一类型!当有一定的透明度时,问题就会出现。

单像素 ARGB 图像的示例:

  public static void imagesTestBiIssue() throws IOException {
  //it also happens with TYPE_INT_ARGB
    BufferedImage bi1 = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
    // rather arbitrary. low values of alpha tend to give more difference
    int argb = 0x11663322; 
    bi1.setRGB(0, 0, argb);
    int p1 = bi1.getRGB(0, 0);
    BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(),
        bi1.getType());
    bi2.getGraphics().drawImage(bi1, 0, 0, null);
    int p2 = bi2.getRGB(0, 0);
    System.out.printf("im1: %08x %s ", p1, formatARGB(p1));
    System.out.printf("im2: %08x %s %s\n", p2, 
        formatARGB(p2), (p1 == p2 ? "" : "DIF"));
  }

 public static String formatARGB(int v) {
    return String.format("(%d,%d,%d,%d)", 
        (v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
  }

这给出:im1: 11663322 (17,102,51,34) im2: 11692d1e (17,105,45,30) DIF

某处似乎有一些颜色转换,我无法想象为什么,因为目标和源是相同的类型。这是预期的(或可接受的)行为吗?


我终于明白了。尝试设置graphics.setComposite(AlphaComposite.Src)。在我自己的库代码中,我这样做了,但我从未考虑过它......

因为默认的组合是AlphaComposite.SrcOver,你实际上是构成半透明像素到完全透明像素,两者都具有非预乘 Alpha,因此这里存在差异。使用AlphaComposite.Src你基本上说只有来源才重要。

另请注意,较低的 alpha 值意味着更透明。这意味着对于低 alpha,RGB 值的重要性较小,因为它们在合成时乘以 alpha(即17/255对于您的示例图像),因此当合成到不透明背景上时,差异不会产生影响。

所以我会说:有些出乎意料?是的。可以接受吗?可能是。 :-)


这是代码的更新版本,使用AlphaComposite.Src,以及没有差异的输出:

public static void main(String[] args) {
    //it also happens with TYPE_INT_ARGB
    BufferedImage bi1 = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
    // rather arbitrary. low values of alpha tend to give more difference
    int argb = 0x11663322;
    bi1.setRGB(0, 0, argb);
    int p1 = bi1.getRGB(0, 0);
    BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(),
            bi1.getType());
    Graphics2D graphics = bi2.createGraphics();
    try {
        graphics.setComposite(AlphaComposite.Src);
        graphics.drawImage(bi1, 0, 0, null);
    }
    finally {
        graphics.dispose();
    }
    int p2 = bi2.getRGB(0, 0);
    System.out.printf("im1: %08x %s ", p1, formatARGB(p1));
    System.out.printf("im2: %08x %s %s\n", p2,
            formatARGB(p2), (p1 == p2 ? "" : "DIF"));
}

public static String formatARGB(int v) {
    return String.format("(%d,%d,%d,%d)",
            (v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
}

Output:

im1: 11663322 (17,102,51,34) im2: 11663322 (17,102,51,34)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BufferedImage.getGraphics().drawImage() 改变像素值 的相关文章

随机推荐

  • 如何在 WebGL 中创建合适的圆角矩形?

    我试图实现答案这个问题 https stackoverflow com questions 43970170 bordered rounded rectangle in glsl但似乎有点问题 如果您打开他们的 ShaderToys 并尝试
  • org.dbunit.dataset.NoSuchTableException,但表存在

    H2 1 4 191 数据库单元 2 5 1 如何解决这个问题 3种情况的代码和结果 org dbunit dataset NoSuchTableException category org dbunit dataset NoSuchTab
  • 为什么我的 wss://(基于 SSL/TLS 的 WebSockets)连接立即断开而不给出任何错误?

    将此发布给遇到同样问题的其他人 我当时正在开发一个浏览器客户端 它使用 stanza io 连接到 XMPP 服务器 在我的例子中是 Prosody 我默认使用 wss 连接 在开发过程中的某个时刻 我的客户端根本无法连接 它会立即无提示地
  • iphone 4.0 以编程方式发送短信

    我正在开发一个简单的应用程序 在其中我需要以编程方式向我的朋友发送短信 所以编写下面的代码来发送短信 MFMessageComposeViewController picker MFMessageComposeViewController
  • 比较 2 个对象数组并删除重复项

    我在 JavaScript 中有 2 个对象数组 想要比较和合并内容并按 id 对结果进行排序 具体来说 生成的排序数组应包含第一个数组中的所有对象 以及第二个数组中具有不在第一个数组中的 id 的所有对象 以下代码似乎有效 减去排序 但必
  • 派生类的初始值设定项列表

    我想要一个派生类 它有一个默认构造函数来初始化继承成员 为什么我可以这样做 class base protected int data class derived public base public derived note data 4
  • wcf 服务不允许 POST

    一般来说 我对 Web 服务还很陌生 并且 我认为 陷入了配置 IIS 和 Web 服务本身的困境 我在 MVS 2010 中创建了一个 wcf Web 服务 并将其托管在 Windows 7 上的 IIS7 5 上 我使用soapUI 4
  • 使用 BCEL 生成的解析字节码确定对象之间的传出耦合(CBO 指标)

    我已经构建了一个程序 它接受提供的 class 文件并使用 BCEL 解析它 我现在已经学会了如何计算 LCOM4 值 现在我想知道如何计算类文件的CBO 对象之间的耦合 值 我已经搜索了整个网络 试图找到关于它的正确教程 但到目前为止我还
  • Gracefull python joblib 杀死

    是否有可能优雅地杀死一个joblib https github com joblib joblib处理 线程后端 并且仍然返回到目前为止的计算结果 parallel Parallel n jobs 4 backend threading r
  • Facebook 对话框、注销和访问令牌(Facebook iOS SDK)

    当使用这样的代码创建 Facebook 对话框时 NSMutableDictionary params NSMutableDictionary dictionaryWithObjectsAndKeys apiKey api key nil
  • Apple Mac 和 Unix 时间戳

    我知道Apple系统上的主要时间戳是CF绝对时间值 也称为Mac绝对时间 它是根据自01 01 2001 00 00 00 UTC以来的秒数计算的32位整数 例如 219216022 解码后为 Thu 13 December 2007 05
  • 在 Objective C 中格式化浮点数

    我需要将浮点数 吸引人的标题 他 格式化为小数点后两位 但前提是这些小数位的值不为零 例子 我有一个名为 answer 的 NSTextField 在使用几个浮点进行一些数学运算后 我想将 answerFloat 变量分配给 answer
  • 无法正确设置PrintArea

    我正在使用 phpspreadsheet v1 3 1 我正在构建一个 Excel 文件 下载 一切正常 唯一的问题是定义 setPrintArea 它总是将标准 PrintArea 返回到 excel 中 基本上 我构建了 Excel 行
  • 根据特定参数值显示或隐藏 SSRS 列

    我无法根据所选参数值显示 隐藏列 我的报告是如何设置的 参数 ImportStatus ImportStatus 参数有三个值可供选择 M V E 如果我选择 ImportStatus value M 那么我希望报告显示特定列 目前 如果我
  • 如何通过扬声器而不是较弱的耳机扬声器播放音频?

    我正在学习核心音频 由于某种原因 处理图的声音仅通过弱 耳机 播放 当您将设备放在耳边时 而不是通过 iPhone 的常规扬声器播放 这是设置音频会话的代码 但我看不到它在哪里配置音频路由 void setupAudioSession AV
  • PivotTable.js 有条件地更改文本颜色

    所以我正在使用 PivotTable js 它对工作有很大帮助 但现在 我正在尝试获取一个过滤器来根据值更改单元格的颜色或单元格内的字体 例如 如果我的数据集中有一个日期数组 dates N A 4 12 2016 7 9 2024 7 9
  • Python 类输入参数

    我是面向对象编程的新手 我的想法是实现以下课程 class name object name def init self name print name 然后的想法是创建该类的两个实例 person1 name jean person2 n
  • JSF 国际化 f:loadbundle 或通过 faces-config:性能点

    有两种方法可以将属性文件加载到 JSF 2 0 中 全球资源包 全局加载属性文件 以便所有jsf页面都可以访问消息 您可以创建一个 faces config xml 文件并显式声明属性文件 面孔配置 xml
  • 使用java进行HTML解析[重复]

    这个问题在这里已经有答案了 可能的重复 可以解析 HTML 文档并构建 DOM 树 java https stackoverflow com questions 1433250 possible to parse a html docume
  • BufferedImage.getGraphics().drawImage() 改变像素值

    这是一个后续previous https stackoverflow com questions 23707736 strange bufferedimage behaviour with 4bits palette问题 标准推荐的改造方式