我正在尝试按照建议的使用BitmapFactory.Options.inBitmap
的做法优化我的应用内存使用量。我想要做的是将位图切成高度为stripeHeight
的条纹,如下所示:
val stripeHeight = 10
val largeBitmap = // the original bitmap
val placeholder = // the bitmap object I want to re purpose for each stripe
val options = BitmapFactory.Options()
options.inBitmap = placeholder
val rows = largeBitmap.height / stripeHeight
for (i in 0 until rows) {
//how can I set the options object into createBitmap?
val stripe = Bitmap.createBitmap(largeBitmap, 0, i * stripeHeight, largeBitmap.width, stripeHeight)
it.onNext(stripe)
}
问题是Bitmap.createBitmap
在其方法签名中不会使用BitmapFactory.Options
。所以我不确定如何告诉android将新位图分配到前一个位图的内存空间。
答案 0 :(得分:0)
一种方法如下:
fun doBitmapProcessing() {
val STRIPE_HEIGHT = 10
//assuming your largeBitmap is a 320x240 ARGB8888 image
val largeBitmap: Bitmap = Bitmap.createBitmap(320, 240, Bitmap.Config.ARGB_8888)
//then allocate a buffer of size 320 * 240 * 4 (4 channels in an ARGB image) bytes
val byteBuffer: ByteBuffer = ByteBuffer.allocate(320 * 240 * 4)
//create a bitmap of desired dimensions for the placeholder
val placeholder: Bitmap = Bitmap.createBitmap(320, STRIPE_HEIGHT, Bitmap.Config.ARGB_8888)
//copy the pixels from your large bitmap to a pre-allocated byte buffer
largeBitmap.copyPixelsToBuffer(byteBuffer)
//create an input stream from the pre-allocated buffer
val inputStream: InputStream = ByteArrayInputStream(byteBuffer.array())
//create the bitmap region decoder
val bitmapRegionDecoder: BitmapRegionDecoder = BitmapRegionDecoder.newInstance(inputStream, true)
//create options, as before
val options = BitmapFactory.Options()
options.inBitmap = placeholder
val rows = largeBitmap.height / STRIPE_HEIGHT
for (i in 0 until rows) {
//call decode stream on the input stream containing your data from *largeImage*, and the options
//in which you specify that you want the memory of *placeholder* to be overwritten.
val region: Rect = Rect(0, i * STRIPE_HEIGHT, largeBitmap.width, i * STRIPE_HEIGHT + STRIPE_HEIGHT)
val stripe: Bitmap = bitmapRegionDecoder.decodeRegion(region, options)
it.onNext(stripe)
}
}
请务必阅读BitmapFactory.Options#inBitmap
的文档,并直接使用BitmapRegionDecoder.decodeRegion(...)
而不是placeholder
的结果,因为无法保证将使用相同的内存位置。
Bitmap.getPixels(...)
& Bitmap.setPixels
:
fun doBitmapProcessing2() {
val STRIPE_HEIGHT = 10
//assuming your largeBitmap is in ARGB 8888 format
val largeBitmap: Bitmap = Bitmap.createBitmap(320, 240, Bitmap.Config.ARGB_8888)
//create a bitmap of desired dimensions for the placeholder
val placeholder: Bitmap = Bitmap.createBitmap(320, STRIPE_HEIGHT, Bitmap.Config.ARGB_8888)
//create int pixel array in which the colors will be saved
val pixels = IntArray(320 * STRIPE_HEIGHT * 4)
val rows = largeBitmap.height / STRIPE_HEIGHT
for (i in 0 until rows) {
//save colors from desired location into the pixels array
largeBitmap.getPixels(pixels, 0, 320, 0, i * STRIPE_HEIGHT, 320, STRIPE_HEIGHT)
//write the colors saved into the array to the placeholder bitmap
placeholder.setPixels(pixels, 0, 320, 0, 0, 320, STRIPE_HEIGHT)
it.onNext(placeholder)
}
}
虽然我对第二个不太确定。 (以前没有使用getPixels
/ setPixels
)
希望这有帮助