Saya mencoba untuk menskalakan dan memutar dalam operasi tunggal sebelum membuat bitmap akhir tetapi preRotate, postConcat tampaknya tidak berfungsi.
Bitmap bmp = ... original image ...
Matrix m = new Matrix()
m.setScale(x, y);
m.preRotate(degrees, (float) width / 2, (float) height / 2);
Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), m, true);
Ini hanya menerapkan skala dan bukan rotasi.
Jawabannya sudah diberikan, tetapi untuk memperjelas bagi siapa pun yang membaca ini:
Tetapi perhatikan bahwa setiap panggilan ke metode "set &" MENGATASI transformasi lainnya. Ini seperti matriks baru. Itulah mengapa rotasi OP's tidak bekerja. Pemanggilan ini tidak dilakukan baris demi baris. Ini seperti dijadwalkan untuk dilakukan pada saat runtime oleh GPU ketika bitmap baru sedang digambar. Ini seperti ketika menyelesaikan matriks Anda, GPU memutarnya, tetapi kemudian, membuat matriks baru yang diskalakan, mengabaikan matriks sebelumnya.
Dan apa perbedaan antara postRotate dan preRotate, misalnya? Nah, matematika matriks ini bukan kekuatan saya, tetapi yang saya tahu adalah bahwa kartu grafis membuat transformasi ini menggunakan perkalian matriks. Sepertinya jauh lebih efisien. Dan sejauh yang saya ingat dari sekolah, ketika mengalikan matriks, urutannya adalah penting. A X B != B X A. Jadi, menskalakan sebuah matriks dan kemudian memutarnya berbeda dengan memutar dan kemudian menskalakannya.
BUUUUT, sejauh hasil akhir di layar sama, kita para programmer tingkat tinggi biasanya tidak perlu mengetahui perbedaan ini. GPU yang tahu.
Nah, dalam kasus-kasus yang jarang terjadi ketika Anda melakukan operasi matriks yang sangat rumit, dan hasilnya tidak seperti yang Anda harapkan atau kinerjanya sangat buruk dan Anda perlu memahami metode-metode ini secara mendalam untuk memperbaiki kode Anda, nah, maka dokumentasi android tidak dapat banyak membantu. Sebaliknya, buku Aljabar Linier yang bagus akan menjadi teman terbaik Anda. ;)
Ini adalah kodenya
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.getWidth();
int height = bitmapOrg.getHeight();
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,
newWidth, newHeight, 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);
}
}
Lihat kode berikut ini, tampaknya berhasil. Dalam kode Anda, Anda mendefinisikan Matrix sebagai m tetapi merujuknya sebagai matrix
public class FourthActivity extends Activity {
private static final int WIDTH = 50;
private static final int HEIGHT = 50;
private static final int STRIDE = 64;
private static int[] createColors() {
int[] colors = new int[STRIDE * HEIGHT];
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
int r = x * 255 / (WIDTH - 1);
int g = y * 255 / (HEIGHT - 1);
int b = 255 - Math.min(r, g);
int a = Math.max(r, g);
colors[y * STRIDE + x] = (a << 24) | (r << 16) | (g << 8) | b;
}
}
return colors;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
final ImageView view1 = (ImageView) findViewById(R.id.imageView1);
int[] colors = createColors();
final Bitmap bmp1 = Bitmap.createBitmap(colors, 0, STRIDE, WIDTH, HEIGHT,
Bitmap.Config.ARGB_8888);
view1.setImageBitmap(bmp1);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
Matrix matrix = new Matrix();
matrix.setScale(2, 2);
matrix.preRotate(45, (float) WIDTH / 2, (float) HEIGHT / 2);
Bitmap bmp2 = Bitmap.createBitmap(bmp1, 0, 0,
bmp1.getWidth(), bmp1.getHeight(), matrix, true);
ImageView view2 = (ImageView) findViewById(R.id.imageView2);
view2.setImageBitmap(bmp2);
}
});
}
}