【问题标题】:Why is there a slight bitmap mismatch between saved png, and, opened png为什么保存的 png 和打开的 png 之间存在轻微的位图不匹配
【发布时间】:2018-02-12 00:30:27
【问题描述】:

我试图在位图中隐藏一个小文件。我将 ARGB 的最低有效位设置为文件中的每个位(我为文件大小保留的位图的前几个像素)。

出于调试目的,我将编码的 int[] 与解码的 int[] 进行比较。每隔几百字节,就有一个不正确的位。

我正在像这样通过 Bitmap.compress 方法保存图片...

OutputStream out = getContentResolver().openOutputStream(fileUri);

picture.compress(Bitmap.CompressFormat.PNG,100,out);

那么,当从图像中提取文件时……

pic = MediaStore.Images.Media.getBitmap(this.getContentResolver(), fileUri);

pic.getPixels(intArr, 0, width, 0, 0, width, height);

我冒昧地检查了其中一个 png,我确实使用 argb8 作为配置,并且使用tweakPNG,发现生成的文件中唯一的块是 IHDR:8 位/样本,真彩色 + alpha,非隔行扫描 sBIT:RGBA8 IDAT 结束

PNG 照片看起来不错,没有问题。

编辑:进展!

我将错误追踪到这个基本问题。
Bitmap.setPixels 的功能与 Bitmap.getpixels 不同。

以下代码显示了converted 和converted2 之间的细微差别。每百个整数大约 1 或 2 位。这对我来说似乎很震惊。这是安卓的bug吗?

    picture3 = Bitmap.createBitmap(picture1.getWidth(), picture1.getHeight(), Bitmap.Config.ARGB_8888);
    picture3.setPixels(converted,0,picture1.getWidth(),0,0,picture1.getWidth(), picture1.getHeight());
    int[] converted2 = new int[converted.length];
    picture3.getPixels(converted2,0,picture1.getWidth(),0,0,picture1.getWidth(), picture1.getHeight());

【问题讨论】:

  • 你认为什么是 argb 值的 lsb?
  • attempting to hide a small file within a bitmap。它看起来更像是隐藏在 png 文件中。
  • greenapps: lsb 是 A: XXXXXXX_ R: XXXXXXX_ G: XXXXXXX_ B: XXXXXXX_ 其中 X 是像素的位,_ 是文件的位。因此,文件的每个字节都存储在像素的 8 个字节上,或者像素文件的 2 个整数表示为 32 位 argb 颜色。而且,是的,我存储在位图中并压缩为 png,因为 png 应该是无损的。
  • 因此,通过设置lsb of an argb value,您需要设置 argb 整数的四个字节中每个字节的 lsb。
  • 首先阅读how to provide a minimal, complete and verifiable examplehow to ask a good question,并确保您编辑了问题正文中的所有必要信息。

标签: android bitmap png


【解决方案1】:

这与this thread 中的问题相同。

我有一个简单的解决方案,只需递增和递减 off A、R、G 或 B 值,直到 lsb(如果每个值都正确)。显然这会导致位图更加失真,但这似乎是我能想到的唯一解决方案。

【讨论】:

    猜你喜欢
    • 2013-09-19
    • 2021-03-24
    • 2011-01-19
    • 1970-01-01
    • 2018-05-21
    • 2017-01-25
    • 2011-06-02
    • 1970-01-01
    • 2012-10-16
    相关资源
    最近更新 更多