2013-01-01 16 views
13

Istnieje nice post autorstwa popularnego programisty Google Romain Guy, który pokazuje, jak efektywnie używać zaokrąglonego narożnika do rysowania (zwanego "StreamDrawable" w his code).Używanie zaokrąglonych narożników do rysowania

Sama próbka działa bardzo dobrze na moim Galaxy S3 w trybie portretowym, ale mam kilka problemów z nim:

  1. jeśli ekran jest mały (na przykład na ekranach QVGA), pokazany obrazy są przycinane.

  2. jeśli mam bitmapę wejściowego, który jest zbyt mały niż jak chcę go pokazać obraz wyjściowy ma jej krawędzie rozmazany. Nawet na Galaxy S3, po uruchomieniu przykładowego kodu i to na krajobraz, to wygląda okropnie:

    enter image description here

  3. ja nadal nie jestem pewien o tym (ponieważ używam obejścia skalowania obrazu do przy użyciu przykładowego kodu), ale wydaje się, że nawet to rozwiązanie jest nieco powolne, gdy jest używane w liście. Może istnieje rozwiązanie do renderscript?

Nie ma znaczenia, czy używam setImageDrawable, czy setBackgroundDrawable. To musi być coś w samym losowaniu.

Próbowałem grać ze zmiennymi i bitmapShader, ale nic nie działało. Niestety, TileMode nie ma wartości dla rozciągania obrazu, tylko układanie go w jakiś sposób.

Jako obejście mogę utworzyć nową skalowaną bitmapę, ale jest to tylko obejście. Z pewnością istnieje lepszy sposób, który nie będzie zużywał więcej pamięci niż powinien.

Jak mogę rozwiązać te problemy i użyć tego świetnego kodu?

+0

powinieneś zamieścić komentarz na temat tego artykułu lub wysłać do niego wiadomość, aby uzyskać odpowiedź tutaj. –

+0

Myślę, że zrobił :) – DaRolla

+0

czy rozwiązałeś problem? – tasomaniac

Odpowiedz

9

Myślę, że rozwiązanie przedstawione na this website działa dobrze.

w przeciwieństwie do innych rozwiązań, nie powoduje przecieków pamięci, mimo że jest oparty na rozwiązaniu Romain Guy.

EDYCJA: teraz w bibliotece pomocy można również użyć RoundedBitmapDrawable (przy użyciu RoundedBitmapDrawableFactory).

+0

Czy możesz wskazać na pomysł (lub gdzieś go mogę znaleźć)? Naprawdę nie mam czasu, aby przeczytać cały ten projekt. – suitianshi

+0

Tak, pomysł jest bardzo oparty na tym, co Romain Guy zaprezentował na swojej stronie internetowej: http://www.curious-creature.org/2012/12/11/android -recipe-1-image-with-rounded-rages /. –

4

Miałem problemy z rozmiarem tego kodu i rozwiązałem go.

Może to pomoże też:

1) w sklepie konstruktora bitmapy w zmiennej lokalnej (np BMP Bitmap prywatnego;)

2) zastępują dwie kolejne metody:

@Override 
    public int getIntrinsicWidth() { 
    return bmp.getWidth(); 
} 

@Override 
    public int getIntrinsicHeight() { 
    return bmp.getHeight(); 
} 

poważaniem, DaRolla

+1

nic mi nie pomogło, a przy okazji, jeśli potrzebujesz tylko szerokości i wysokości bitmapy, możesz przechowywać je zamiast tego i ustaw je w CTOR. –

+0

@DaRolla Dzięki za wskazanie, że zaoszczędziło mi to dużo czasu. – CanC

0
nie

Podstawowym problemem jest to, że BitmapShader na TileMode nie posiada skalowania o Ption. Zauważysz w źródle, że został ustawiony na Shader.TileMode.CLAMP i docs opisać jako:

replikować kolor krawędzi, jeśli shader rysuje poza jej pierwotnych granicach

Aby obejść ten problem istnieją trzy rozwiązania:

  1. ograniczyć wielkość widoku, w którym odkształcalny używanej do wielkości bitmapy.
  2. Ogranicz obszar rysunku; na przykład zmienić:

    int width = bounds.width() - mMargin; 
    int height = bounds.height() - mMargin; 
    mRect.set(mMargin, mMargin, width, height); 
    

    Do:

    int width = Math.min(mBitmap.getWidth(), bounds.width()) - mMargin; 
    int height = Math.min(mBitmap.getHeight(), bounds.height()) - mMargin; 
    mRect.set(mMargin, mMargin, width, height); 
    
  3. skalować bitmap do wielkości rozciągliwej. I został przeniesiony do tworzenia shaderów onBoundsChange() i zdecydowały się utworzyć nową bitmapę stąd:

    bitmap = Bitmap.createScaledBitmap(mBitmap, width, height, true); 
    mBitmapShader = new BitmapShader(bitmap, 
         Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
    

    Zauważ, że to potencjalnie powolne działanie i zostanie uruchomiony w głównym wątku. Możesz zastanowić się, jak chcesz ją wdrożyć, zanim przejdziesz do tego ostatniego rozwiązania.

+0

jakie są zalety i wady każdej z tych metod? trzeci jest oczywiście powolny i zużywa więcej pamięci, ale co z pozostałymi? który polecasz? –

+0

Jeśli chcesz, aby mapa bitowa rozciągała się do rozmiaru widoku, niektóre implementacje podobne do ostatnich są prawie jedynym sposobem, aby przejść przy użyciu 'BitmapShadera'. Pierwsza ograniczy rozmiar samego widoku, podczas gdy druga będzie tylko malować moduł cieniujący w lewym górnym rogu widoku. –

+0

cóż, a co jeśli chcę, aby zachowywał się jak normalny imageView, tylko że spowoduje, że obraz będzie miał zaokrąglone rogi? –

Powiązane problemy