Android的 - 如何获取或设置(打印)新闻部的JPEG文件(每英寸点数),而装载或以编程方式保存它? [英] Android - how to get or set (print) DPI ( dots per inch ) of JPEG file while loading or saving it programmatically?

查看:270
本文介绍了Android的 - 如何获取或设置(打印)新闻部的JPEG文件(每英寸点数),而装载或以编程方式保存它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an app developed on Android versions 4.0 and above. ( The app does not support Android versions below 4.0 [Ice Cream Sandwich] ).

现在的问题是有关(的JPEG或PNG的当量)格式的各种图像(打印)DPI。

The question is related to (print) DPI of various images ( for eg. of jpeg or png ) format.

这个问题并不涉及到屏幕DPI或各种Android设备的尺寸。它也没有涉及到示出了屏幕尺寸的装置上的位图。

This question does NOT relate to SCREEN DPI or sizes of various Android devices. It is also NOT related to showing the Bitmap on the device in screen size.

我使用下面的code加载在位图的图像文件。然后,我一直在种植,并将其保存为JPEG格式的另一个文件jpegCom pression。我已经能够通过以下code要做到这一点,但我无法得到的加载DPI或设置保存图像文件的DPI。

I am using the following code to load the image file in 'Bitmap'. Then I have been cropping it and saving it to another file in JPEG format with jpegCompression. I have been able to do this by the following code, but I am unable to get DPI of loaded or set the DPI of saved Image file.

所以,我有两个问题。

1)我怎样才能获得(打印)新闻部从JPEG文件,之后或同时加载在位图?

1) How can I get the (print) DPI from the JPEG file, after or while loading it in 'Bitmap'?

2)当保存新产生的位图,我怎么能在JPEG文件重新设置DPI?

2) While saving the new generated 'Bitmap', how can I set the DPI again in the JPEG file?

以下是code,以供参考的部分。

Following is the part of code for reference.

    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;

我试图找到从计算器和其他网站通过谷歌搜索,但未能得到正确的答案相关的。所以我决定问它在这个论坛。

I have tried to find from stackoverflow and from other sites by googling, but could not get the proper related answer. So I have decided to ask it in this forum.

您提示和建议是欢迎的。

Your hints and suggestions are welcome.

桑杰。

推荐答案

您指的是DPI元数据写成JPEG文件的一部分?我一直在努力与最近却想出了一个解决方案。如果你已经解决了它,这个答案可以帮助别人谁遇到同样的问题。

Are you referring to the DPI metaData written as part of the JPEG file? I have struggled with that recently but came up with a solution. If you have already solved it, this answer can help others who run into the same problem.

在一个位图是COM pressed为JPEG的机器人,它保存在一个JFIF段格式。请参阅文章在这里( http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format )。我还附上一个Android JPEG图像的截图开辟了一个十六进制编辑器,所以你可以看到它是如何匹配。

When a Bitmap is compressed to JPEG in Android, it saves it in a JFIF segment format. Please see article here(http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format). I have also attached a screenshot of an Android jpeg image opened up in a hex editor so you can see how it matches.

要编辑值,你需要首先创建一个byte []数组将存储Bitmap.com preSS()。这里是我的code的一部分,我做到这一点(输入为源位图)。

To edit the value, you need to first create a byte[] array that will store the Bitmap.compress(). Here is a part of my code where I do just that(input being the source Bitmap).

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

根据对JFIF结构,你需要编辑13日,14日,15日,16日,17日和索引的字节数组中开始。 13日指定密度型,14日和15日在X分辨率,16日和17日举行的Y轴分辨率。就我而言,我把它改为500 DPI的元数据中的X和Y轴分辨率。这种转换为0000 0001 1111 0100这是1F4十六进制。然后我写了byte []的归档,复制它从我的手机我的电脑,并验证查看图像属性时的细节是present。

Based on the JFIF structure, you need to edit the 13th, 14th, 15th, 16th, and 17th indexes in the byte array. 13th specifying the density type, 14th and 15th the X resolution, and 16th and 17th holding the Y resolution. In my case, I changed it to 500 dpi as the X and Y resolution in the metadata. This translated to 0000 0001 1111 0100 which is 1F4 in hex. I then wrote the byte[] to file, copied it from my phone to my computer, and verified the details were present when viewing the image properties.

                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为一个字节。解决的办法是把你的价值为十进制,然后使用(字节)铸造。

NOTE: Java uses a signed byte system and you cannot enter in any binary value above 127 without the compiler barking at you. I ran into this problem inputting F4 as a byte. The solution is to convert your value to decimal and then use a (byte) cast.

希望这有助于!

这篇关于Android的 - 如何获取或设置(打印)新闻部的JPEG文件(每英寸点数),而装载或以编程方式保存它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆