2012-01-26 19 views
70

znajduje się zdanie w android canvas.drawBitmap(visiblePage, 0, 0, paint);jak obrócić bitmapę 90 stopni

Kiedy dodać canvas.rotate(90), nie ma efektu. Ale jeśli napiszę

canvas.rotate(90) 
canvas.drawBitmap(visiblePage, 0, 0, paint); 

Nie otrzymam rysowanej bitmapy. Co więc nie robię dobrze?

+0

I odpowiedziałeś to tutaj: http://stackoverflow.com/questions/8608734/android-rotate-bitmap-9 0-stopni-wyników-w-zmiażdżony-obraz-potrzeba-a-prawdziwy-obrót-b/14475148 # 14475148 – EyalBellisha

Odpowiedz

10

Poniżej znajduje się kod, aby obrócić lub ponownie zmienić rozmiar obrazu w android

public class bitmaptest extends Activity { 
    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     LinearLayout linLayout = new LinearLayout(this); 

     // load the origial BitMap (500 x 500 px) 
     Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), 
       R.drawable.android); 

     int width = bitmapOrg.width(); 
     int height = bitmapOrg.height(); 
     int newWidth = 200; 
     int newHeight = 200; 

     // calculate the scale - in this case = 0.4f 
     float scaleWidth = ((float) newWidth)/width; 
     float scaleHeight = ((float) newHeight)/height; 

     // createa matrix for the manipulation 
     Matrix matrix = new Matrix(); 
     // resize the bit map 
     matrix.postScale(scaleWidth, scaleHeight); 
     // rotate the Bitmap 
     matrix.postRotate(45); 

     // recreate the new Bitmap 
     Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, 
          width, height, matrix, true); 

     // make a Drawable from Bitmap to allow to set the BitMap 
     // to the ImageView, ImageButton or what ever 
     BitmapDrawable bmd = new BitmapDrawable(resizedBitmap); 

     ImageView imageView = new ImageView(this); 

     // set the Drawable on the ImageView 
     imageView.setImageDrawable(bmd); 

     // center the Image 
     imageView.setScaleType(ScaleType.CENTER); 

     // add ImageView to the Layout 
     linLayout.addView(imageView, 
       new LinearLayout.LayoutParams(
         LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT 
       ) 
     ); 

     // set LinearLayout as ContentView 
     setContentView(linLayout); 
    } 
} 

Można również sprawdzić ten link do szczegółów: http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

+0

To nie działa, jeśli obraz nie jest kwadratowy – xavimb

175

Można również próbować ten jeden

Matrix matrix = new Matrix(); 

matrix.postRotate(90); 

Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmapOrg,width,height,true); 

Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true); 

Następnie można użyć obróconego obrazu, aby ustawić w swoim widoku obrazu przez

imageView.setImageBitmap(rotatedBitmap); 
+1

Myślę, że na scaledBitmap chcesz (bitmapOrg, szerokość, wysokość, prawda) – Jameo

+1

Który import macierzy? android.graphics lub android.opengl? – Poutrathor

+2

Importuj android.graphics – kirtan403

128
public static Bitmap RotateBitmap(Bitmap source, float angle) 
{ 
     Matrix matrix = new Matrix(); 
     matrix.postRotate(angle); 
     return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); 
} 

Aby uzyskać bitmapę z zasobów:

Bitmap source = BitmapFactory.decodeResource(this.getResources(), R.drawable.your_img); 
+1

thx arvis .. świetne rozwiązanie – Antonio

+0

Jestem nowy z Androidem. Zastanawiam się tylko, czy wykonuję Bitmap newBitmap = RotateBitmap (oldBitmap, 90), czy moja "zdekodowana bitmapa" ma dwa bloki pamięci (stare i nowe) lub czy odnoszą się one do tej samej pamięci, ale nie ma rotacji, a inne mają rotację ? .... Martwię się, jeśli zdekoduję R.drawable.picture na oldBitmap, jeśli przypuszczam, że zajmie to 2 MB pamięci (Heap chyba?), To newBitmap zabiorą dodatkowe 2 MB pamięci (tj. 2+ 2 = łącznie 4 MB)?lub czy nowa mapa bitowa będzie odwoływać się tylko do starej mapy bitowej (a zatem nie jest wymagane dodatkowe 2 MB)? ......... Chcę uniknąć błędu outOfMemory za wszelką cenę! –

+3

@ShishirGupta Nie testowany, ale przez androidy: 'Jeśli źródłowa mapa bitowa jest niezmienna, a żądany podzbiór jest taki sam, jak sama źródłowa bitmapa, wówczas źródłowa bitmapa jest zwracana i nie jest tworzona nowa mapa bitowa. – Arvis

6

Domyślnie punkt rotacja jest (0,0) punkt płótna, a wydaje mi się, że może chcesz obrócić go wokół centrum. Zrobiłem to:

protected void renderImage(Canvas canvas) 
{ 
    Rect dest,drawRect ; 

    drawRect = new Rect(0,0, mImage.getWidth(), mImage.getHeight()); 
    dest = new Rect((int) (canvas.getWidth()/2 - mImage.getWidth() * mImageResize/2), // left 
        (int) (canvas.getHeight()/ 2 - mImage.getHeight()* mImageResize/2), // top 
        (int) (canvas.getWidth()/2 + mImage.getWidth() * mImageResize/2), //right 
        (int) (canvas.getWidth()/2 + mImage.getHeight()* mImageResize/2));// bottom 

    if(!mRotate) { 
     canvas.drawBitmap(mImage, drawRect, dest, null); 
    } else { 
     canvas.save(Canvas.MATRIX_SAVE_FLAG); //Saving the canvas and later restoring it so only this image will be rotated. 
     canvas.rotate(90,canvas.getWidth()/2, canvas.getHeight()/ 2); 
     canvas.drawBitmap(mImage, drawRect, dest, null); 
     canvas.restore(); 
    } 
} 
1

Jeśli obracać bitmapę, 90 180 270 360 jest ok, ale dla innych stopni płótno wyciągnie bitmapę o różnej wielkości.

Więc najlepszym sposobem jest

canvas.rotate(degree,rotateCenterPoint.x,rotateCenterPoint.y); 
canvas.drawBitmap(...); 
canvas.rotate(-degree,rotateCenterPoint.x,rotateCenterPoint.y);//rotate back 
2

Krótki rozszerzenie dla Kotlin

fun Bitmap.rotate(degrees: Float): Bitmap { 
    val matrix = Matrix().apply { postRotate(degrees) } 
    return Bitmap.createBitmap(this, 0, 0, width, height, matrix, true) 
} 

i użytkowania:

val rotatedBitmap = bitmap.rotate(90) 
Powiązane problemy