farklı bellek özelliklerine sahip Android'de bir bit eşlem yeniden boyutlandırmak için üç baskın yolu vardır:
Bu API mevcut bitmap'te almak ve bir YENİ bit eşlemi yaratacak seçtiğiniz boyutlar.
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, , bu API çalışmak için mevcut bitmap gerektirir. 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ı almak açısından daha fazla, ama ek bellek yükü açısından korkunç. Bunun gibi, bu bilinçli belleği inSampleSize flag
Bellek açısından bakıldığında, inSampleSize
kullanımı gerçekten hızlı bir işlemdir. Etkin olarak, görüntünüzün her X. pikseli yalnızca sonuçta elde ettiğiniz bitmap'e çözer.
Size kesin kararlar vermez: gerçi inSampleSize
ile iki ana sorunlar var. Sadece bitmap'in boyutunu yalnızca 2 gücüyle azaltır.
En iyi kalitede yeniden boyutlandırma'u üretmez. Yeniden boyutlandırılan filtrelerin çoğu, piksel bloklarını okuyarak iyi görünen görüntüler oluşturur ve ardından söz konusu yeniden boyutlandırılan pikseli üretmek için onları ağırlığa sokar.inSampleSize
, yalnızca birkaç pikselin hepsini okuyarak bunu engeller. Sonuç oldukça performanslıdır ve düşük hafızadır, ancak kalite zarar görür. Yalnızca bazı pow2 boyutuna göre görüntüyü küçülen uğraşıyoruz ve filtreleme sorunu değilse
, o zaman inSampleSize
daha fazla bellek verimli (veya performans verimli) yöntemi bulamıyor. Eğer iki gücüne eşit olmayan bir boyuta bir görüntü ölçeklendirme gerekiyorsa
inScaled, inDensity, inTargetDensity flags
, o zaman BitmapOptions
ait inScaled
, inDensity
ve inTargetDensity
bayrakları gerekir. inScaled
bayrağı ayarlandığında, sistem inTargetDensity
değerlerini inDensity
değerlerine bölerek ölçekleme değerinizi bitmap'inize uygulayacaktır.
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);
resim boyutunda yeniden ve ayrıca ek hesaplamalar dikkate alınmıştır çünkü boyutlandırma adımı sırasında Sonuçta daha iyi bakacağız, yani buna bir 'yeniden boyutlandırma filtresi' uygulanacak bu yöntemi kullanarak . Ancak uyarıda bulunun: Ekstra filtre adımı olan , ekstra işlem süresi alır ve büyük resimler için hızlı bir şekilde ekleyebilir, sonuçta yavaş yeniden boyutlandırmalar ve filtrenin kendisinde ekstra bellek ayırmalarına neden olabilir.
Bu tekniği, ek filtreleme ek yükünden dolayı, istediğiniz boyuttan önemli ölçüde daha büyük olan bir görüntüye uygulamak genellikle iyi bir fikir değildir.
bir bellek ve performans açısından bakıldığında Sihirli Kombinasyon
, en iyi sonuçlar için bu seçenekleri birleştirebilirsiniz.
inSampleSize
ilk görüntünün uygulanacaktır (inSampleSize
, inScaled
, inDensity
ve inTargetDensity
bayrakları ayarlama) onu alma hedef boyutundan daha güç-iki BÜYÜK yanında yer almaktadır. Ardından, görüntüyü temizlemek için bir filtre işlemi uygulayarak sonucu istediğiniz boyutlara ölçeklendirmek için inDensity
& kullanılır.
inSampleSize
adımı, elde edilen Yoğunluk tabanlı adımın yeniden boyutlandırma filtresini uygulamasının gerekeceği piksel sayısını azaltacağından, bu ikisinin birleştirilmesi çok daha hızlı bir işlemdir.
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);
belirli boyutlarda ve bazı güzel filtrelemeye bir görüntü sığdırmak gerek ediyorsanız, o zaman bu teknik doğru boyutta almak için en iyi köprü olmakla hızlı, düşük bellek ayak izi yapılır operasyon. senin bit eşlem yeniden boyutlandırmak için resmin tamamını deşifre olmadan görüntü boyutunu alma
Alma resim boyutları
, gelen boyutlarını bilmek gerekir. Görüntünün boyutlarını elde etmenize yardımcı olması için inJustDecodeBounds
bayrağını 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
Önce boyutunu çözmek için bu bayrağı kullanabilirler ve sonra hedef çözünürlüğe ölçeklendirme uygun değerlerini hesaplayabilir .
Sunucunuzun doğru boyutunu göndermemesi, böylece müşterinin RAM'ini ve bant genişliğinizi koruyabilir !? – James
Sadece sunucu kaynağına sahip olsaydım, onunla birlikte bir hesaplama bileşeni vardı ve her durumda, henüz görmediği en boy oranları için görüntülerin tam boyutlarını tahmin edebilirdi. Eğer kaynak içeriği üçüncü taraf bir CDN'den yüklüyorsanız (benim gibi) işe yaramazsa :( –