cách xoay một bitmap 90 độ


123

Có một tuyên bố trong android canvas.drawBitmap(visiblePage, 0, 0, paint);

Khi tôi thêm canvas.rotate(90), không có hiệu lực. Nhưng nếu tôi viết

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

Tôi không nhận được bitmap nào được vẽ. Vì vậy, những gì tôi đang làm không đúng?


Tôi đã trả lời điều này ở đây: stackoverflow.com/questions/8608734/…
EyalBellisha

Câu trả lời:


254

Bạn cũng có thể thử cái này

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);

Sau đó, bạn có thể sử dụng hình ảnh được xoay để đặt trong chế độ xem hình ảnh của mình

imageView.setImageBitmap(rotatedBitmap);

1
Tôi nghĩ rằng bạn muốn có scaleedBitmap (bitmapOrg, width, height, true)
Jameo

2
Nhập ma trận nào? android.graphics hay android.opengl?
Poutrathor

6
Nhập android.graphics
kirtan403 10/12/15

4
điều này sử dụng rất nhiều bộ nhớ. Đối với các ảnh bitmap lớn, nó có thể gây ra sự cố do có nhiều bản sao của các ảnh bitmap trong bộ nhớ.
Moritz Cả hai

1
Trong trường hợp bạn không cần bitmap gốc, hãy gọi bitmap.recycle()để chắc chắn.
Nick Bedford

174
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);
}

Để lấy Bitmap từ các tài nguyên:

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

1
Tôi là người mới với Android. Chỉ tự hỏi nếu tôi làm Bitmap newBitmap = RotateBitmap (oldBitmap, 90), 'bitmap được giải mã' của tôi có hai khối bộ nhớ (cho cũ và mới) hay chúng đề cập đến cùng một bộ nhớ, nhưng một khối không có xoay, khối khác có xoay. ? .... Mối quan tâm của tôi là, nếu tôi giải mã R.drawable.picture thành oldBitmap, nếu giả sử nó chiếm 2 MB bộ nhớ (Tôi đoán là Heap?), Liệu newBitmap có chiếm thêm 2 MB bộ nhớ không (tức là 2 + 2 = Tổng 4MB)? hay newBitmap sẽ chỉ tham chiếu đến oldBitmap (và do đó không cần thêm 2MB)? ......... Tôi muốn tránh lỗi outOfMemory bằng mọi giá!
Shishir Gupta

4
@ShishirGupta Không được kiểm tra mà bởi tài liệu android:If the source bitmap is immutable and the requested subset is the same as the source bitmap itself, then the source bitmap is returned and no new bitmap is created.
Arvis

1
@Arvis Này arvis Tôi đã thử gợi ý của bạn và nó phù hợp với định hướng tuy nhiên bây giờ tôi nhận được một hình ảnh tập trung vào chân dung nhỏ hơn nhiều. Có ý kiến ​​gì không?
Doug Ray

44

Phần mở rộng ngắn cho Kotlin

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

Và cách sử dụng:

val rotatedBitmap = bitmap.rotate(90F) // value must be float

13

Dưới đây là mã để xoay hoặc kích thước lại hình ảnh của bạn trong 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);
    }
}

Bạn cũng có thể kiểm tra liên kết này để biết chi tiết: http://www.anddev.org/resize_and_rotate_image_-_example-t621.html


6

Theo mặc định, điểm xoay là điểm (0,0) của Canvas và tôi đoán là bạn có thể muốn xoay nó xung quanh tâm. Tôi đã làm điều đó:

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();
    }
}

4

Tôi sẽ đơn giản hóa hàm mở rộng Kotlin của comm1x hơn nữa:

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

4

Sử dụng createBitmap()phương pháp Java, bạn có thể vượt qua các mức độ.

Bitmap bInput /*your input bitmap*/, bOutput;
float degrees = 45; //rotation degree
Matrix matrix = new Matrix();
matrix.setRotate(degrees);
bOutput = Bitmap.createBitmap(bInput, 0, 0, bInput.getWidth(), bInput.getHeight(), matrix, true);

1

Nếu bạn xoay bitmap, 90 180 270 360 là ok nhưng đối với các độ khác canvas sẽ vẽ bitmap với kích thước khác.

Vì vậy, cách tốt nhất là

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

0

Trong trường hợp mục tiêu của bạn là có hình ảnh được xoay trong imageView hoặc tệp, bạn có thể sử dụng Exif để đạt được điều đó. Thư viện hỗ trợ hiện cung cấp: https://android-developers.googleblog.com/2016/12/introductioning-the-exifinterface-support-library.html

Dưới đây là cách sử dụng của nó nhưng để đạt được mục tiêu của bạn, bạn phải kiểm tra tài liệu api của thư viện về điều đó. Tôi chỉ muốn đưa ra một gợi ý rằng xoay bitmap không phải lúc nào cũng là cách tốt nhất.

Uri uri; // the URI you've received from the other app
InputStream in;
try {
  in = getContentResolver().openInputStream(uri);
  ExifInterface exifInterface = new ExifInterface(in);
  // Now you can extract any Exif tag you want
  // Assuming the image is a JPEG or supported raw format
} catch (IOException e) {
  // Handle any errors
} finally {
  if (in != null) {
    try {
      in.close();
    } catch (IOException ignored) {}
  }
}

int rotation = 0;
int orientation = exifInterface.getAttributeInt(
    ExifInterface.TAG_ORIENTATION,
    ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
  case ExifInterface.ORIENTATION_ROTATE_90:
    rotation = 90;
    break;
  case ExifInterface.ORIENTATION_ROTATE_180:
    rotation = 180;
    break;
  case ExifInterface.ORIENTATION_ROTATE_270:
    rotation = 270;
    break;
}

sự phụ thuộc

biên dịch "com.android.support:exifinterface:25.1.0"


0

Chỉ cần cẩn thận kiểu Bitmap từ nền tảng java gọi như từ comm1x 's và Gnzlt ' s câu trả lời, bởi vì nó có thể trở về null. Tôi nghĩ rằng nó cũng linh hoạt hơn nếu tham số có thể là bất kỳ Số nào và sử dụng infix để dễ đọc, tùy thuộc vào phong cách mã hóa của bạn.

infix fun Bitmap.rotate(degrees: Number): Bitmap? {
    return Bitmap.createBitmap(
        this,
        0,
        0,
        width,
        height,
        Matrix().apply { postRotate(degrees.toFloat()) },
        true
    )
}

Cách sử dụng?

bitmap rotate 90
// or
bitmap.rotate(90)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.