2014-02-19 1 views
7

Android 4.0 이상에서 개발 된 앱이 있습니다. (이 앱은 4.0 [Ice Cream Sandwich] 이하의 Android 버전을 지원하지 않습니다.)안드로이드 - 프로그래밍 방식으로 JPEG 파일을로드하거나 저장하는 동안 JPEG 파일의 DPI (dots per inch)를 얻거나 설정 (인쇄)하는 방법은 무엇입니까?

질문은 다양한 이미지 (예 : jpeg 또는 png) 형식의 (인쇄) DPI와 관련이 있습니다.

이 질문은 SCREEN 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; 

내가 검색 한 결과 stackoverflow 및 다른 사이트에서 찾으려고했지만 적절한 관련 답변을 얻을 수 없습니다. 그래서 나는이 포럼에서 그것을 요구하기로 결정했다.

귀하의 힌트와 제안을 환영합니다.

산 제이.

답변

4

JPEG 파일의 일부로 작성된 DPI metaData를 언급하고 있습니까? 나는 최근에 어려움을 겪었지만 해결책을 내놓았다. 이미 해결했다면이 대답은 같은 문제를 겪고있는 다른 사람들을 도울 수 있습니다.

비트 맵을 Android에서 JPEG로 압축하면 JFIF 세그먼트 형식으로 저장됩니다. 여기 기사를 참조하십시오 (http://en.wikipedia.org/wiki/JPEG_File_Interchange_Format). 또한 16 진수 편집기에서 열어 본 Android jpeg 이미지의 스크린 샷을 첨부하여 어떻게 일치하는지 확인할 수 있습니다. enter image description here


이 값을 수정하려면) (먼저 Bitmap.compress를 저장하는 바이트 [] 배열을 만들 필요가있다. 여기에 내 코드의 일부가있다. (입력은 소스 비트 맵 임).

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

는 JFIF 구조를 기반으로, 당신은 바이트 배열에 13, 14, 15, 16, 및 17 인덱스를 편집해야합니다. 밀도 유형을 지정하는 13 번째, X 해상도를 14 번째 및 15 번째, Y 해상도를 보유하는 16 번째 및 17 번째. 제 경우에는 메타 데이터의 X 및 Y 해상도로 500 dpi로 변경했습니다. 이것은 16 진수로 1F4 인 0000 0001 1111 0100으로 변환됩니다. 그런 다음 바이트 []를 파일에 쓰고, 내 휴대폰에서 내 컴퓨터로 복사 한 다음 이미지 속성을 볼 때 세부 사항이 존재하는지 확인했습니다.

   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); 

참고 : 자바 부호있는 바이트 시스템을 사용하고 당신이 당신을 짖는 컴파일러없이 127 위 바이너리 값을 입력 할 수 없습니다.F4를 바이트로 입력하는 문제에 직면했습니다. 해결책은 값을 십진수로 변환 한 다음 (바이트) 형변환을 사용하는 것입니다.

희망이 도움이됩니다. 그냥 여기 편의를 위해

+0

GR8을, 내가 할 수있었습니다을 제 3 자 라이브러리 sanselanandroid를 사용하여 동일한 작업을 수행합니다. 그러나이 방법은 더 빠르고 더 빠릅니다. 이 방법은 Exif 정보의 데이터를 변경합니다. 이 방법을 사용하면 이미지에 축소판이없는 JPEG 'X 해상도'와 'Y 해상도'를 변경할 수 있습니다. Photos (엄지 손톱과 더 많은 exif 정보가있는 전문 카메라에서 찍은 사진)을 사용해 보았을 때 DPI를 Sanselan 방식으로 직접 설정할 수 없었습니다. – SHS

8

사본에 준비가되어 방법 붙여 넣기 :

저장된 파일이 이미지 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); 
} 

:

enter image description here

+0

Gr8 - 새로운 Android 개발자를위한 솔루션을 간소화합니다. – SHS