我注意到,当跨设备以JPEG格式读取相同的照片时,像素值不匹配。它们很接近,但又有所不同。转换为PNG文件时,像素值似乎匹配。
这似乎是由于跨设备的(非)压缩算法引起的。无论如何,这就是我想到的。有没有办法读取JPEG文件,以便跨设备从照片中检索相同的像素?我在BitmapFactory选项组件中看不到任何选项。
当前,在跨设备处理图像的像素值时,将应用以下内容来保持大小:
Options options = new Options();
options.inScaled = false;
options.inPreferQualityOverSpeed = true;
目前,将像素与以下像素进行比较只是看几个像素(接近匹配,但不相等):
int[] pixels = new int[bitmapF.getWidth() * bitmapF.getHeight()];
bitmapF.getPixels(pixels, 0, bitmapF.getWidth(), 0, 0, bitmapF.getWidth(), bitmapF.getHeight());
Log.d("pixel entries", "pixels = " + pixels[233] + " - " + pixels[4002] + " - " + pixels[11391]);
注意:如果读取未压缩的同一文件的PNG版本,则值与预期的相同。
例如,三星Galaxy S4和三星Galaxy S5甚至具有与 Assets 文件夹中存储的相同jpeg(运行相同的测试 Activity )不同的像素。
例如,pixel [233]在s5上为-5205635,在s4上为-5336451。像素[4002]也有点偏离。但是在此jpeg图片上,两个设备上的pixel [11391]相等。
最佳答案
JPEG标准不要求解码器实现产生逐位相同的输出图像。不幸的是,指定解码器要求的标准文档ISO 10918-2显然不能在线免费获得,但是Wikipedia says:
使用相同输入的不同解码器输出之间的差异通常是由于内部精度水平不同而引起的,尤其是在执行IDCT时。差异的另一个可能来源是平滑,它试图减少“块状”伪像。
像您一样,我希望设置inPreferQualityOverSpeed
会产生相同的输出,但实际上并不能保证这一点。我可以想到至少有两种方法可以使两部不同的手机有较小的差异:
BitmapFactory
的实现发生了变化(例如inPreferQualityOverSpeed
被破坏然后被修复,反之亦然),或者BitmapFactory
所利用的不同硬件功能(例如,矢量指令集,DSP协处理器等)。标量浮点单位的差异甚至都可能导致差异,尤其是在JIT编译产生实际机器指令的情况下。 考虑到标准中的摆动空间以及您的实验观察,看来保证逐位协议(protocol)的唯一方法是在自己的应用程序中执行解码。也许您可以找到一些其他的Android兼容库。