기본적으로 안드로이드 애플 리케이션에서 비트 맵 (이미지에서) 회전하려고합니다. 이 작업을 수행하려는 이유는 카메라에서 찍은 사진 (의도를 통해)이 세로로 캡처 되어도 가로로 표시되고 이미지의 방향이 메타 데이터로 유지된다는 것입니다. 잘못하면 나를 바로 잡으십시오. 그러나 문제는 이미지가로드 될 때 많은 양의 메모리가 필요하다는 것입니다. OutOfMemoryError가 발생하지 않고 이미지를 회전하고 저장하는 방법을 찾지 못했습니다. . 필요한 경우OutOfMemoryError 또는 다운 스케일없이 안드로이드에서 이미지 회전
가- 이미지의로드가 이미지 뷰
- 에
- 부하 표시 용의 축소 된 버전을 회전 할 필요가있는 경우
- 체크가 작은 화상을 를 회전 : 나 어디 다음 코드는
- 별도의 스레드에서; 이미지를로드, 회전 및 저장하므로 나중에 필요하지 않습니다.
응용 프로그램에서 이미지를 해상도로 유지하는 것이 중요하지만 인코딩이있는 모든 트릭을 환영합니다. 나는 며칠 동안 인터넷을 검색했지만 이미 구현 한 것 이상을 찾을 수 없습니다. 여기 주제에 또 하나의 실이 있지만 해결책이없는 것 같습니다. 당신이 도울 수 있기를 바랍니다.
public Bitmap getBitmap(final Context c) {
if (bitmap != null)
return bitmap;
final int rotate = necessaryRotation(c, file);
// if(rotate != 0) rotateImageFile(c, rotate);
try {
// Get scaled version
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, options);
options.inSampleSize = calcInSampleSize(options, 1024, 1024);
options.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file, options);
// rotate?
bitmap = rotateImage(c,bitmap,rotate);
System.out.println("Bitmap loaded from file: size="
+ bitmap.getWidth() + "," + bitmap.getHeight());
System.gc();
} catch (Exception e) {
System.err.println("Unable to load image file: "
+ this.getFilename());
}
// if rotation is needed, do it in worker thread for next time
if(rotate != 0){
Thread t = new Thread(new Runnable(){
public void run() {
// load entire image
try{
File imageFile = new File(getFilename());
Bitmap huge = Media.getBitmap(c.getContentResolver(),
Uri.fromFile(imageFile));
huge = rotateImage(c,huge,rotate);
// save bitmap properly
FileOutputStream out = new FileOutputStream(imageFile);
huge.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
huge.recycle();
huge = null;
out = null;
System.gc();
}catch(IOException e){
e.printStackTrace();
}
}
});
t.start();
}
return bitmap;
}
private Bitmap rotateImage(Context c, Bitmap bitmap, int rotate) {
if (rotate != 0) {
// rotate
Matrix m = new Matrix();
m.postRotate(rotate);
Bitmap rotImage = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
bitmap.getHeight(), m, true);
bitmap.recycle();
System.out.println("Image (id=" + getId()
+ ") rotated successfully");
System.gc();
return rotImage;
}
return bitmap;
}
private int necessaryRotation(Context c, String imageFile) {
int rotate = 0;
ExifInterface exif;
try {
exif = new ExifInterface(imageFile);
int orientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return rotate;
}
private int calcInSampleSize(BitmapFactory.Options options, int reqWidth,
int reqHeight) {
int height = options.outHeight;
int width = options.outWidth;
int inSampleSize = 1;
while (height > reqHeight || width > reqWidth) {
height /= 2;
width /= 2;
inSampleSize *= 2;
}
return inSampleSize;
}
내가 최대 힙 크기 제한 장벽을 제거하여 메모리 부족을 피할 수있는 멋진 JNI 솔루션을 만들었습니다. [** ** 링크 **] (http://stackoverflow.com/questions/14398670/android-rotating-a-bitmap-using-jni-ndk#comment20033361_14398670)를 내 스 니펫에 추가하십시오. 몇 가지 참고 사항 : - 코드에서 "uint16_t"의 모든 인스턴스를 "uint32_t"로 바꿉니다 (이는 내가 묻는 내 코드의 버그입니다). - 입력 및 출력 비트 맵은 8888 구성 (ARGB)이어야합니다. 입력 비트 맵은 프로세스 중에 재활용됩니다. - 코드는 90도 시계 반대 방향으로 이미지를 회전시킵니다. 물론 당신은 그것을 바꿀 수 있습니다. –