Android 2.2를 실행하는 내 기기에서 애플리케이션을 개발하고 테스트 중입니다. 내 코드에서 BitmapFactory.decodeResource를 사용하여 검색 한 Bitmap을 사용 bitmap.setPixels()
하고이를 호출 하여 변경할 수 있습니다. 나는 안드로이드 1.6를 실행하는 친구의 디바이스에서이를 테스트 할 때, 나는 얻을 IllegalStateException
에 대한 호출에 bitmap.setPixels
. 온라인 설명서에 따르면 IllegalStateException
비트 맵이 변경 불가능한 경우이 메서드에서이 발생합니다. 문서는 decodeResource
불변 비트 맵을 반환하는 것에 대해 아무것도 말하지 않지만 분명히 그럴 것입니다.
두 번째 Bitmap
객체 를 필요로하지 않고 응용 프로그램 리소스에서 변경 가능한 비트 맵을 안정적으로 가져 오기 위해 다른 호출을 수행 할 수 있습니까 (동일한 크기 의 변경 가능한 비트 맵을 만들고이를 래핑하는 Canvas에 그릴 수 있지만 동일한 크기의 비트 맵 두 개가 필요함) 내가 의도했던 것보다 두 배 더 많은 메모리를 사용)?
변경 불가능한 비트 맵을 변경 가능한 비트 맵으로 변환 할 수 있습니다.
하나의 비트 맵의 메모리 만 사용하는 수용 가능한 솔루션을 찾았습니다.
소스 비트 맵은 디스크 (램 메모리 없음)에 원시 저장 (RandomAccessFile) 된 다음 소스 비트 맵이 해제되고 (이제 메모리에 비트 맵이 없음) 그 후에 파일 정보가 다른 비트 맵에로드됩니다. 이렇게하면 시간당 램 메모리에 하나의 비트 맵 만 저장되어있는 비트 맵 복사본을 만들 수 있습니다.
여기에서 전체 솔루션 및 구현보기 : Android : 변경 불가능한 비트 맵을 변경 가능으로 변환
이제 모든 유형의 비트 맵 (ARGB_8888, RGB_565 등)에서 작동하는이 솔루션에 개선 사항을 추가하고 임시 파일을 삭제합니다. 내 방법을 참조하십시오.
/**
* Converts a immutable bitmap to a mutable bitmap. This operation doesn't allocates
* more memory that there is already allocated.
*
* @param imgIn - Source image. It will be released, and should not be used more
* @return a copy of imgIn, but muttable.
*/
public static Bitmap convertToMutable(Bitmap imgIn) {
try {
//this is the file going to use temporally to save the bytes.
// This file will not be a image, it will store the raw image data.
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "temp.tmp");
//Open an RandomAccessFile
//Make sure you have added uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
//into AndroidManifest.xml file
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
// get the width and height of the source bitmap.
int width = imgIn.getWidth();
int height = imgIn.getHeight();
Config type = imgIn.getConfig();
//Copy the byte to the file
//Assume source bitmap loaded using options.inPreferredConfig = Config.ARGB_8888;
FileChannel channel = randomAccessFile.getChannel();
MappedByteBuffer map = channel.map(MapMode.READ_WRITE, 0, imgIn.getRowBytes()*height);
imgIn.copyPixelsToBuffer(map);
//recycle the source bitmap, this will be no longer used.
imgIn.recycle();
System.gc();// try to force the bytes from the imgIn to be released
//Create a new bitmap to load the bitmap again. Probably the memory will be available.
imgIn = Bitmap.createBitmap(width, height, type);
map.position(0);
//load it back from temporary
imgIn.copyPixelsFromBuffer(map);
//close the temporary file and channel , then delete that also
channel.close();
randomAccessFile.close();
// delete the temp file
file.delete();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return imgIn;
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다