Bu yanıt,
ölçeği küçültülmüş bir bitmap sürümünü yüklemek için inSampleSize'ın nasıl kullanılacağını açıklayan Büyük bitmap'leri Etkin Şekilde Yükleme bölümünde özetlenmiştir .
Özellikle Ön ölçeklendirme bitmapleri , çeşitli yöntemlerin ayrıntılarını, bunların nasıl birleştirileceğini ve hangilerinin en verimli bellek olduğunu açıklar.
Android'de farklı bellek özelliklerine sahip bir bit eşlemi yeniden boyutlandırmanın üç baskın yolu vardır:
createScaledBitmap API'si
Bu API, mevcut bir bitmap'i alacak ve seçtiğiniz tam boyutlara sahip YENİ bir bitmap oluşturacaktır.
Artı tarafta, tam olarak aradığınız görüntü boyutunu elde edebilirsiniz (nasıl göründüğüne bakılmaksızın). Ancak olumsuz yanı , bu API'nin çalışması için mevcut bir bitmap gerektirmesidir . Yani yeni, daha küçük bir sürüm oluşturmadan önce görüntünün yüklenmesi, kodunun çözülmesi ve bir bitmap oluşturulması gerekir. Bu, tam boyutlarınızı elde etmek açısından idealdir, ancak ek bellek yükü açısından korkunçtur. Bu nedenle, bellek bilincine sahip olma eğiliminde olan çoğu uygulama geliştiricisi için bu bir tür anlaşma kırıcıdır.
inSampleSize bayrağı
BitmapFactory.Options
inSampleSize
geçici bir bit eşlem olarak kod çözme ihtiyacını ortadan kaldırmak için, kod çözerken görüntünüzü yeniden boyutlandıracak bir özelliğe sahiptir . Burada kullanılan bu tam sayı değeri, 1 / x küçültülmüş boyutta bir görüntü yükleyecektir. Örneğin, inSampleSize
2 olarak ayarlamak yarı boyutta bir görüntü verir ve 4 olarak ayarlamak boyutun 1 / 4'ü olan bir görüntü verir. Temel olarak, görüntü boyutları her zaman kaynak boyutunuzdan iki kat daha küçük olacaktır.
Bellek perspektifinden, kullanmak inSampleSize
gerçekten hızlı bir işlemdir. Etkili bir şekilde, görüntünüzün yalnızca her X'inci pikselinin kodunu sonuçta elde ettiğiniz bit eşlem olarak çözecektir. Yine de iki ana sorun var inSampleSize
:
Size kesin kararlar vermez . Bitmap'inizin boyutunu yalnızca 2'nin bir gücü kadar azaltır.
En iyi kalitede yeniden boyutlandırma sağlamaz . Çoğu yeniden boyutlandırma filtresi, piksel bloklarını okuyarak ve ardından söz konusu yeniden boyutlandırılmış pikseli oluşturmak için bunları ağırlıklandırarak iyi görünen görüntüler üretir. inSampleSize
tüm bunları, sadece birkaç pikselde bir okuyarak önler. Sonuç, oldukça performanslı ve düşük bellek, ancak kalite zarar görüyor.
Görüntünüzü yalnızca bir pow2 boyutunda küçültmekle uğraşıyorsanız ve filtreleme bir sorun değilse, o zaman daha fazla bellek açısından verimli (veya performans açısından verimli) bir yöntem bulamazsınız inSampleSize
.
inScaled, inDensity, inTargetDensity işaretleri
Bir görüntüyü ikinin kuvvetine eşit olmayan bir boyuta ölçeklemeniz gerekiyorsa inScaled
, inDensity
ve inTargetDensity
işaretlerine ihtiyacınız olacak BitmapOptions
. Ne zaman inScaled
bayrağı ayarlandı, ölçeklendirme değer elde edecek sistem bölerek bitmap uygulamak için inTargetDensity
tarafından inDensity
değerlerden.
mBitmapOptions.inScaled = true;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeResources(getResources(),
mImageIDs, mBitmapOptions);
Bu yöntemi kullanmak resminizi yeniden boyutlandıracak ve ayrıca ona bir 'yeniden boyutlandırma filtresi' uygulayacaktır, yani sonuç daha iyi görünecektir, çünkü yeniden boyutlandırma adımında bazı ek matematik hesaba katılmıştır. Ancak dikkat edin: bu ekstra filtre adımı fazladan işlem süresi alır ve büyük görüntüler için hızlı bir şekilde toplanabilir , bu da yavaş yeniden boyutlandırmalara ve filtrenin kendisi için ekstra bellek ayırmalarına neden olabilir.
Ekstra filtreleme ek yükü nedeniyle, bu tekniği istediğiniz boyuttan önemli ölçüde daha büyük bir görüntüye uygulamak genellikle iyi bir fikir değildir.
Sihirli Kombinasyon
Bellek ve performans açısından, en iyi sonuçlar için bu seçenekleri birleştirebilirsiniz. (ayarı inSampleSize
, inScaled
, inDensity
ve inTargetDensity
bayraklar)
inSampleSize
ilk olarak resme uygulanacak ve onu hedef boyutunuzdan daha büyük olan bir sonraki ikiye katlayacak. Ardından, sonucu tam olarak istediğiniz boyutlara ölçeklendirmek için inDensity
& inTargetDensity
kullanılır, görüntüyü temizlemek için bir filtre işlemi uygulanır.
Bu ikisini birleştirmek çok daha hızlı bir işlemdir, çünkü bu inSampleSize
adım sonuçta ortaya çıkan Yoğunluğa dayalı adımın yeniden boyutlandırma filtresini uygulamak için ihtiyaç duyacağı piksel sayısını azaltacaktır.
mBitmapOptions.inScaled = true;
mBitmapOptions.inSampleSize = 4;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth * mBitmapOptions.inSampleSize;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeFile(fileName, mBitmapOptions);
Bir görüntüyü belirli boyutlara sığdırmanız ve daha iyi bir filtreleme yapmanız gerekiyorsa, bu teknik doğru boyutu elde etmek için en iyi köprüdür, ancak hızlı, düşük bellek alanıyla yapılır.
Görüntü boyutlarını alma
Tüm görüntünün kodunu çözmeden görüntü boyutunu elde etme Bit eşleminizi yeniden boyutlandırmak için, gelen boyutları bilmeniz gerekir. inJustDecodeBounds
Piksel verilerinin şifresini çözmeniz gerekmeden, görüntünün boyutlarını elde etmenize yardımcı olması için bayrağı kullanabilirsiniz .
// Decode just the boundaries
mBitmapOptions.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName, mBitmapOptions);
srcWidth = mBitmapOptions.outWidth;
srcHeight = mBitmapOptions.outHeight;
//now go resize the image to the size you want
Bu bayrağı, önce boyutu çözmek ve ardından hedef çözünürlüğünüze ölçeklemek için uygun değerleri hesaplamak için kullanabilirsiniz.