cara memutar bitmap 90 derajat

123

Ada pernyataan di android canvas.drawBitmap(visiblePage, 0, 0, paint);

Saat saya tambahkan canvas.rotate(90), tidak ada efek. Tetapi jika saya menulis

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

Saya tidak mendapatkan bitmap yang ditarik. Jadi apa yang tidak saya lakukan dengan benar?

murli
sumber
Saya telah menjawab ini di sini: stackoverflow.com/questions/8608734/…
EyalBellisha

Jawaban:

254

Anda juga bisa mencoba yang ini

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

Kemudian Anda dapat menggunakan gambar yang diputar untuk diatur dalam tampilan gambar Anda

imageView.setImageBitmap(rotatedBitmap);
Arya
sumber
1
Saya pikir untuk scaledBitmap yang Anda inginkan (bitmapOrg, lebar, tinggi, benar)
Jameo
2
Impor matriks yang mana? android.graphics atau android.opengl?
Poutrathor
6
Impor android.graphics
kirtan403
4
ini menggunakan banyak memori. Untuk bitmap besar, ini dapat menimbulkan masalah karena banyak salinan bitmap di memori.
Moritz Keduanya
1
Jika Anda tidak membutuhkan bitmap asli, panggil bitmap.recycle()untuk memastikan.
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);
}

Untuk mendapatkan Bitmap dari sumber daya:

Bitmap source = BitmapFactory.decodeResource(this.getResources(), R.drawable.your_img);
Arvis
sumber
1
Saya baru mengenal android. Hanya bertanya-tanya apakah saya melakukan Bitmap newBitmap = RotateBitmap (oldBitmap, 90), apakah 'bitmap yang didekodekan' saya memiliki dua blok memori (untuk lama dan baru) atau apakah mereka mengacu pada memori yang sama, tetapi yang satu tidak memiliki rotasi, yang lain memiliki rotasi ? .... Kekhawatiran saya adalah, jika saya mendekode R.drawable.picture ke dalam oldBitmap, jika dianggap membutuhkan 2 MB memori (Heap saya kira?), Apakah newBitmap akan mengambil tambahan 2 MB memori (yaitu 2 + 2 = Total 4MB)? atau apakah newBitmap hanya merujuk ke oldBitmap (dan karenanya tidak diperlukan tambahan 2MB)? ......... Saya ingin menghindari kesalahan outOfMemory dengan cara apa pun!
Shishir Gupta
4
@ShishirGupta Tidak diuji tetapi oleh dokumen 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 Hai arvis Saya mencoba saran Anda dan berfungsi untuk orientasi namun sekarang saya mendapatkan gambar yang berpusat pada potret yang jauh lebih kecil. Ada ide?
Doug Ray
44

Ekstensi pendek untuk Kotlin

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

Dan penggunaan:

val rotatedBitmap = bitmap.rotate(90F) // value must be float
Pavel Shorokhov
sumber
13

Di bawah ini adalah kode untuk memutar atau mengubah ukuran gambar Anda di 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);
    }
}

Anda juga dapat memeriksa tautan ini untuk detailnya: http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

Arslan Anwar
sumber
6

Secara default, titik rotasi adalah titik Canvas (0,0), dan perkiraan saya adalah Anda mungkin ingin memutarnya di sekitar tengah. Saya melakukan itu:

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

Saya akan lebih menyederhanakan fungsi ekstensi Kotlin dari comm1x :

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

Menggunakan createBitmap()metode Java, Anda dapat memberikan derajat.

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);
Googlian
sumber
1

Jika Anda memutar bitmap, 90 180270360 tidak apa-apa, tetapi untuk derajat lainnya kanvas akan menggambar bitmap dengan ukuran berbeda.

Jadi, cara terbaik adalah

canvas.rotate(degree,rotateCenterPoint.x,rotateCenterPoint.y);  
canvas.drawBitmap(...);
canvas.rotate(-degree,rotateCenterPoint.x,rotateCenterPoint.y);//rotate back
王怡飞
sumber
0

Jika tujuan Anda adalah memiliki gambar yang diputar dalam imageView atau file, Anda dapat menggunakan Exif untuk mencapainya. Pustaka dukungan sekarang menawarkan itu: https://android-developers.googleblog.com/2016/12/introducing-the-exifinterface-support-library.html

Di bawah ini adalah penggunaannya tetapi untuk mencapai tujuan Anda, Anda harus memeriksa dokumentasi api perpustakaan untuk itu. Saya hanya ingin memberi petunjuk bahwa memutar bitmap tidak selalu merupakan cara terbaik.

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

ketergantungan

kompilasi "com.android.support:exifinterface:25.1.0"

Ultimo_m
sumber
0

Berhati-hatilah dengan jenis Bitmap dari panggilan platform java seperti dari jawaban comm1x dan Gnzlt , karena mungkin mengembalikan null. Menurut saya juga lebih fleksibel jika parameternya bisa berupa Angka apa saja dan menggunakan infix agar mudah dibaca, tergantung gaya pengkodean Anda.

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

Cara Penggunaan?

bitmap rotate 90
// or
bitmap.rotate(90)
HendraWD
sumber