Android JPEG图像在多个设备上具有不同的像素值

Android JPEG图像在多个设备上具有不同的像素值,android,jpeg,Android,Jpeg,我注意到,当在JPEG格式的设备上读取相同的照片时,像素值不匹配。他们很接近,但不同。转换为PNG文件时,像素值似乎匹配 这似乎是由于跨设备的(非)压缩算法造成的。不管怎么说,我就是这么想的。有没有办法读入JPEG文件,以便跨设备从照片中检索相同的像素?我在BitmapFactory选项组件中没有看到选项 当前,在跨设备处理图像的像素值时,应用以下方法来保持大小: Options options = new Options(); options.inScaled = false; options

我注意到,当在JPEG格式的设备上读取相同的照片时,像素值不匹配。他们很接近,但不同。转换为PNG文件时,像素值似乎匹配

这似乎是由于跨设备的(非)压缩算法造成的。不管怎么说,我就是这么想的。有没有办法读入JPEG文件,以便跨设备从照片中检索相同的像素?我在BitmapFactory选项组件中没有看到选项

当前,在跨设备处理图像的像素值时,应用以下方法来保持大小:

Options options = new Options();
options.inScaled = false;
options.inPreferQualityOverSpeed = true;
当前将像素与以下像素进行比较,只是为了查看一些(接近匹配,但不相等):

注意:如果读取同一未压缩文件的PNG版本,则值与预期值相同。

例如,三星Galaxy S4和三星Galaxy S5甚至具有存储在资产文件夹中的相同jpeg(运行相同测试活动)的不同像素


例如,像素[233]在s5上为-5205635,但在s4上为-5336451。像素[4002]也有点不清晰。但是,在这张jpeg图片上,像素[11391]在两台设备上是相等的。

我想您还应该检查压缩PNG在设备上的显示方式是否相同


如果答案是肯定的,那么剩下的唯一一件事就是找出如何在手机上以编程方式将这些图像转换为相同类型的压缩png

JPEG解码器的大部分工作涉及实数计算。通常这是通过使用定点整数算法来实现的。这会引入舍入误差。细微的变化是使用JPEG的自然部分。

JPEG标准不要求解码器实现产生逐位相同的输出图像。不幸的是,指定解码器要求的标准文件显然不能在网上免费获得,但:

……JPEG标准(以及类似的MPEG标准)包括解码的一些精度要求,包括解码过程的所有部分(可变长度解码、逆DCT、去量化、输出的重新规范化);参考算法的输出不得超过:

  • 每个像素组件的最大差值为1位
  • 每个8×8像素块上的低均方误差
  • [等]
使用相同输入的不同解码器输出之间的差异通常是由于内部精度的不同,特别是在执行IDCT时。差异的另一个可能来源是平滑,它试图减少“块状”瑕疵

和您一样,我希望设置
inPreferQualityOverSpeed
将产生相同的输出,但实际上没有任何东西可以保证这一点。我可以想出至少两种方法,让您在两款不同的手机上获得小的变化:

  • 手机可能运行不同版本的Android,
    BitmapFactory
    的实现发生了变化(例如,
    inPreferQualityOverSpeed
    可能被破坏并修复,反之亦然),或者
  • 手机可能提供
    位图工厂
    所利用的不同硬件功能(例如向量指令集、DSP协处理器等)。甚至标量浮点单元之间的差异也可能导致差异,特别是在JIT编译生成实际机器指令的情况下

  • 考虑到标准中的摇摆空间加上您的实验观察,保证比特对比特一致性的唯一方法似乎是在您自己的应用程序中执行解码。也许您可以找到其他与Android兼容的库。

    将媒体大小重新调整为所需大小,或使用HTML属性禁用图像缩放


    另一个选项是允许用户在加载缩略图后做出决定以节省带宽。

    是的,不同设备的像素颜色值不同。这是非常烦人的,尤其是如果你想比较颜色。解决方法是(通过人类感知)在视觉上比较相同的颜色

    通过人类感知比较两种颜色的最佳方法之一是CIE76。这种差异称为Delta-E。当它小于1时,人眼无法识别这种差异

    您可以找到奇妙的颜色实用程序类(),其中包括CIE76比较方法。这是由苏黎世大学的Daniel Strebel写的。 在ColorUtils.class中,我使用以下方法:

    static double colorDifference(int r1, int g1, int b1, int r2, int g2, int b2)
    
    r1、g1、b1-第一种颜色的RGB值

    r2、g2、b2-要比较的第二种颜色的RGB值

    如果您使用Android,您可以获得如下值:

    r1=Color.red(像素)

    g1=Color.green(像素)


    b1=Color.blue(像素)

    我也有同样的问题。 PNG和JPEG图像似乎是由不同的设备近似渲染的。
    我们使用BMP图像解决了这个问题(不幸的是,这些图像的尺寸要大得多)。

    为什么整数算法会在具有相同内部图片的设备之间变化?当解码相同的JPEG图像并接收相同的舍入误差时,操作系统不会使用相同的计算吗?假设解码器使用缩放整数进行DCT计算。64位系统可以为相同的计算提供比32位系统更高的精度。解码器可能使用浮点计算,给出不同的舍入误差。解码器可以使用不同的操作顺序进行不同的取整。有不同的方法来优化DCT/IDCT计算。如果您希望像素值相同,而不考虑硬件,请在一台机器上转换PNG,并在不同的硬件设备上解码为PNG。但是,这些图像仅供参考
    static double colorDifference(int r1, int g1, int b1, int r2, int g2, int b2)