使用一般的固定标头创建JPEG缩略图图像

nho*_*ass 6 java android jpeg image image-processing

我想为我的照片(如Facebook的预览照片)创建预览缩略图。我的计划:

  • 发件人:从原始照片中生成一个缩放的拇指(最大尺寸为30px),去掉所有固定的标题以发送。
  • 接收者:从“最小化”字节数组中,添加固定的标头(客户端代码中的硬编码)。然后将其转换Bitmap为显示。

最后,我提出了基于Q42.ImagePreview的解决方案。

我将这些部分拆分为固定标题:

  • 图像开始(0xFFD8
  • App0(以开头0xFFE0
  • 定义量化表
  • 定义霍夫曼表

动态部分是:

  • 帧开始(以开头0xFFC0):因为它包含宽度/高度字节。
  • 开始扫描(以开始0xFFDA)。
  • 压缩图像数据。
  • 图片结尾(0xFFD9

但是它只能在我的其中1台设备上使用,而不能在其他设备上使用。

那么,如何生成可在Android和iOS设备上使用的固定的,通用的和标准的JPEG标头

谢谢。


更多详情:

生成缩小的数据流:

  • 使用BitmapFactory&从原始图像创建缩放的位图(最大尺寸为30px,保持宽高比)Matrix

  • 压缩缩放位图质量64使用Bitmap#compress()并储存byte[] thumbData

  • thumbData上面的子数组从头到尾排列0xFFDA。(SOS,图像数据和EOI)并存储在中byte[] body

  • 以代表宽度和高度的4个字节为前缀body,转换为Base64字符串并发送。

在正常工作的设备中,其大小thumbData比其他不工作的设备长。霍夫曼表,SOS和图像数据部分则有所不同,请参见: 在2张图像照片之间进行差异检查

Nha*_*ran 5

恐怕你无法使用每个平台的内置方法来做到这一点。问题出在压缩阶段。

\n\n

JPEG 压缩中有许多变量,包括扫描、样本、DHT 选择和 DQT 选择的类型和细分。如果您使用的编码器中的任何一个不同,您将得到不同的输出。这是野兽的本性。

\n\n

例如:定义霍夫曼表 (DHT) 定义如何压缩“图像数据”(在 SoS 段之后)。并且您仅使用固定的霍夫曼表进行解码,这就是导致问题的原因。

\n\n
\n\n

因此,您可能有一些选项可供选择:

\n\n
    \n
  • 缩小到最大尺寸后发送全质量图像(不压缩)30px作为预览缩略图照片。
  • \n
  • 编写您自己的压缩算法或使用跨平台库。
  • \n
  • 将整个原始图像上传到您的服务器以处理并将“缩小的数据”发送回 Android/iOS。
  • \n
\n\n
\n\n

Telegram也有预览照片,他们的做法和你类似。但他们将整个原始图像(以字节数组形式)传输到服务器,创建拇指照片,去掉“固定标题”并将“缩小数据”发送回接收器。

\n\n

当在移动设备上接收时,它们将“缩小数据”解码为位图,通过附加“固定标头”(Bitmaps.java#L111)并更新 SoF 段中的图像大小。请参阅ImageLoader.java#L750

\n