java - 使用通用固定标题创建 JPEG 拇指图像

标签 java android image image-processing jpeg

我想为我的照片创建预览缩略图,例如 Facebook's preview photo .我的计划:

  • 发件人:从原始照片生成缩放缩略图(最大尺寸为 30 像素),去除所有固定标题以发送。
  • Receiver:从“缩小的”字节数组,附加固定 header (客户端代码中的硬编码)。然后转换为Bitmap显示。

最后我想出了基于 Q42.ImagePreview 的解决方案.

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

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

动态部分是:

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

但它只适用于我的一台设备,不适用于其他设备。

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

谢谢。


更多细节:

生成缩小的数据流:

  • 使用 BitmapFactoryMatrix

    从原始图像创建缩放位图(最大尺寸 30 像素,保持宽高比)
  • 使用 Bitmap#compress() 压缩质量为 64 的缩放位图并存储在 byte[] thumbData 中。

  • 将上面的thumbData0xFFDA 分列到末尾。 (SOS、图像数据和 EOI)并存储在 byte[] body 中。

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

在正常工作的设备中,thumbData 的大小比其他不工作的设备长。不同之处在于霍夫曼表、SOS 和图像数据部分,请参见: Diff check between 2 image photos

最佳答案

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

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

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


所以你可能有一些选择:

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

Telegram 也有预览图,他们的做法和你差不多。但他们将整个原始图像(以字节数组形式)传输到服务器,创建缩略图,去除“固定 header ”并将“缩小数据”发回给接收者.

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

关于java - 使用通用固定标题创建 JPEG 拇指图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56236805/

相关文章:

java - 如何声明不同类型的HashMap?

Android:如何使用文本创建启动画面

java - 谷歌网址缩短不起作用

javascript - 您如何获得 API Key 以访问服务预授权?

php - 如何转换 BLOB 图像在网页中显示

java - 如何使用 java XPATH 处理空 XML 标签?

java - 如何使用 Java 在 CascadeClassifier 中设置裁剪大小

java - Stateless Apache Wicket 无状态页面/请求

jQuery 文档准备就绪事件

.net - 将 .Net 面板控件导出到图像