Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android-如何在以编程方式加载或保存JPEG文件时获取或设置(打印)JPEG文件的DPI(每英寸点数)?_Android_Image_Printing_Bitmap_Dpi - Fatal编程技术网

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

Android-如何在以编程方式加载或保存JPEG文件时获取或设置(打印)JPEG文件的DPI(每英寸点数)?,android,image,printing,bitmap,dpi,Android,Image,Printing,Bitmap,Dpi,我有一个在安卓4.0及以上版本上开发的应用程序。(该应用程序不支持低于4.0[冰淇淋三明治]的Android版本) 这个问题与各种图像(例如jpeg或png)格式的(打印)DPI有关 这个问题与屏幕DPI或各种Android设备的大小无关。它也与在设备上以屏幕大小显示位图无关 我正在使用以下代码加载“位图”中的图像文件。然后我裁剪了它,并用JPEG压缩将它保存到另一个JPEG格式的文件中。我已经能够做到这一点,通过以下代码,但我无法获得DPI的加载或设置DPI的保存图像文件 所以我有两个问题 1

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

这个问题与各种图像(例如jpeg或png)格式的(打印)DPI有关

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

我正在使用以下代码加载“位图”中的图像文件。然后我裁剪了它,并用JPEG压缩将它保存到另一个JPEG格式的文件中。我已经能够做到这一点,通过以下代码,但我无法获得DPI的加载或设置DPI的保存图像文件

所以我有两个问题

1) 在“位图”中加载JPEG文件后或加载时,如何从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;
我曾试图通过谷歌搜索stackoverflow和其他网站,但没有找到正确的相关答案。所以我决定在这个论坛上提问

欢迎您的提示和建议


Sanjay.

您指的是作为JPEG文件一部分编写的DPI元数据吗?我最近一直在努力解决这个问题,但我找到了一个解决办法。如果你已经解决了这个问题,这个答案可以帮助其他遇到同样问题的人

当位图在Android中压缩为JPEG时,它将以JFIF段格式保存。请看这里的文章()。我还附上了一张Android jpeg图像的屏幕截图,它是在一个十六进制编辑器中打开的,所以你可以看到它是如何匹配的

要编辑该值,首先需要创建一个字节[]数组来存储位图。compress()。这是我的代码的一部分,我就是这样做的(输入是源位图)

根据JFIF结构,需要编辑字节数组中的第13、14、15、16和17个索引。13指定密度类型,14和15表示X分辨率,16和17表示Y分辨率。在我的例子中,我将其更改为500 dpi,作为元数据中的X和Y分辨率。这转换为0000 0001 1111 0100,十六进制为1F4。然后我将字节[]写入文件,将其从手机复制到计算机,并在查看图像属性时验证是否存在详细信息

                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使用带符号的字节系统,如果没有编译器的提示,您无法输入127以上的任何二进制值。我在输入F4作为字节时遇到了这个问题。解决方案是将值转换为十进制,然后使用(字节)转换


希望这有帮助

为了方便起见,这里提供了复制粘贴方法:

保存的文件将正确设置图像DPI值:


Gr8,通过使用第三方库Android,我也可以做到这一点。但是这种方法更好更快。这种方法会更改Exif info中的数据。通过这种方法,我们可以更改jpeg的“X分辨率”和“Y分辨率”,其中图像没有缩略图。当我尝试使用照片(从专业相机拍摄,它有缩略图和更多exif信息)时,我无法直接设置DPI以及Sanselan way.Gr8-简化android新开发人员的解决方案。这是一种JPEG文件格式,但有人知道PNG文件吗?
                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);
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);
}