Android – 如何获取或设置(打印)加载或编程保存JPEG文件的DPI(每英寸点数)?

我有一个Android 4.0及以上版本开发的应用程序。 (该应用程序不支持4.0以下的Android版本[冰淇淋三明治])。

这个问题涉及(打印)各种图像(例如JPEG或PNG)格式的DPI。

这个问题不涉及屏幕DPI或各种Android设备的大小。 它也与在屏幕上显示设备上的位图无关。

我正在使用下面的代码来加载图像文件在'位图'。 然后,我已经裁剪,并保存到另一个jpegCompression JPEG格式的文件。 我已经能够通过下面的代码做到这一点,但我无法得到DPI的加载或设置保存的图像文件的DPI。

所以我有两个问题。

1)在“位图”中加载后如何从JPEG文件中获取(打印)DPI?

2)在保存新生成的“位图”的同时,如何在JPEG文件中再次设置DPI?

以下是供参考的部分代码。

FileInputStream inputStream = new FileInputStream(theSourcePhotoFilePathName); Bitmap bitmap = null; BitmapRegionDecoder decoder = null; BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 1; options.inDensity = 300; // Tried this but not working. try { decoder = BitmapRegionDecoder.newInstance(in, false); bitmap = decoder.decodeRegion(region, options); // the region has cropping coordinates. } catch (IllegalArgumentException e){ Log.d("First Activity", "Failed to recycle bitmap for rect=" + region, e); } catch (IOException e) { Log.d("First Activity", "Failed to decode into rect=" + region, e); } finally { if (decoder != null) decoder.recycle(); } inputStream.close(); inputStream = null; FileOutputStream fos = new FileOutputStream( theTargetTempFolderDestFilePath ); bitmap.compress(CompressFormat.JPEG, jpegCompressionRatio, fos); fos.flush(); fos.close(); fos = null; 

我试图find从stackoverflow和其他网站通过谷歌search,但无法得到适当的相关答案。 所以我决定在这个论坛上提问。

欢迎您提示和build议。

桑杰。

Solutions Collecting From Web of "Android – 如何获取或设置(打印)加载或编程保存JPEG文件的DPI(每英寸点数)?"

只是为了方便这里准备复制和粘贴方法:

 public static void saveBitmapToJpg(Bitmap bitmap, File file, int dpi) throws IOException { ByteArrayOutputStream imageByteArray = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, imageByteArray); byte[] imageData = imageByteArray.toByteArray(); setDpi(imageData, dpi); FileOutputStream fileOutputStream = new FileOutputStream(file); fileOutputStream.write(imageData); fileOutputStream.close(); } private static void setDpi(byte[] imageData, int dpi) { imageData[13] = 1; imageData[14] = (byte) (dpi >> 8); imageData[15] = (byte) (dpi & 0xff); imageData[16] = (byte) (dpi >> 8); imageData[17] = (byte) (dpi & 0xff); } 

保存的文件将具有正确的图像DPI值:

在这里输入图像说明

你是指作为JPEG文件的一部分写入的DPI元数据? 我最近一直在努力,但提出了一个解决scheme。 如果你已经解决了这个问题,这个答案可以帮助那些遇到同样问题的人。

在Android中将位图压缩为JPEG时,会将其保存为JFIF段格式。 请参阅这里的文章( http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format )。 我还附加了一个在hex编辑器中打开的Android jpeg图像截图,以便您可以看到它是如何匹配的。

在这里输入图像说明

要编辑该值,您需要先创build一个将存储Bitmap.compress()的byte []数组。 这里是我的代码的一部分,我只是这样做(input是源位图)。

 ByteArrayOutputStream uploadImageByteArray = new ByteArrayOutputStream(); input.compress(Bitmap.CompressFormat.JPEG, 100, uploadImageByteArray); byte[] uploadImageData = uploadImageByteArray.toByteArray(); 

基于JFIF结构,您需要编辑字节数组中的第13,14,15,16和17个索引。 13号指定密度types,14号和15号分辨率,16号和17号分辨率。 就我而言,我将其更改为500 dpi,作为元数据中的X和Y分辨率。 这翻译成0000 0001 1111 0100这是hex的1F4。 然后,我将byte []写入文件,将其从手机复制到我的计算机,并在查看图像属性时validation了详细信息。

  uploadImageData[13] = 00000001; uploadImageData[14] = 00000001; uploadImageData[15] = (byte) 244 uploadImageData[16] = 00000001; uploadImageData[17] = (byte) 244 File image = new File(Environment .getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) .getAbsolutePath() + "/meta Images/", imageFileName); FileOutputStream sdCardOutput = new FileOutputStream(image); sdCardOutput.write(uploadImageData); 

注: Java使用有符号的字节系统,不能在编译器咆哮的情况下input127以上的任何二进制值。 我碰到这个问题inputF4作为一个字节。 解决方法是将您的值转换为十进制,然后使用(字节)强制转换。

希望这可以帮助!