Intereting Posts
Как применить анимацию fade-in / fade-out при замене фрагмента Активность андроида просочилась в окно com.android.internal.policy.impl.phonewindow $ decorview Проблема Как заставить Android Studio загружать зависимости из источников и javadoc? Размещение видео внутри видеообзора Обновить пользовательский интерфейс из потока Помощь в получении String Array из файла arrays.xml Тест эспрессо завершился неудачно после успешного нажатия и блокировки в течение 60 секунд Необязательный метод в интерфейсе Java Как я могу поймать SIGSEGV (ошибка сегментации) и получить трассировку стека под JNI на Android? Как использовать собственный шрифт с помощью WebView Android, org.simpleframework.xml Исключение стойкости, элемент «foo» уже используется Android 5.0: как изменить цвет названия последних приложений? Создание неопределенного шага прогресса на ActionBar Как получить ширину строки на Android? Обновление программного обеспечения Android-приложения Phonegap программно

Масштабирование и поворот растрового изображения с использованием Matrix в Android

Я пытаюсь масштабировать и вращать в одиночной операции до того, как выстроить окончательный битмап, но preRotate, postConcat, похоже, не работает.

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

Применяется только масштаб, а не вращение.

Solutions Collecting From Web of "Масштабирование и поворот растрового изображения с использованием Matrix в Android"

Пожалуйста, проверьте эту ссылку.

http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

Это код

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

Ответ был дан, но для того, чтобы кто-нибудь читал это:

1) если вы хотите выполнить ONE-преобразование в вашем растровом изображении, вы можете использовать SET (setRotate, setScale и т. Д.).

Но обратите внимание, что любой вызов метода «set» OVERRIDES других преобразований. Это похоже на новую матрицу. Поэтому вращение OP не работало. Эти вызовы не выполняются по строкам. Это похоже на то, что они планируются во время выполнения графическим процессором при рисовании нового растрового изображения. Это как при разрешении матрицы, GPU повернул ее, но затем создал новую масштабированную, игнорируя предыдущую матрицу.

2) если вы хотите выполнить более одного преобразования, то вы ДОЛЖНЫ использовать методы «pre» или «post».

И в чем разница между postRotate и preRotate, например? Ну, эта математическая математика не моя сила, но я знаю, что графические карты делают эти преобразования, используя матричное умножение. Это кажется более эффективным. И, насколько я помню из школы, при умножении матриц порядок важен. AXB! = BX A. Итак, масштабируйте матрицу, а затем вращайте ее, отличную от поворота, а затем масштабируйте ее.

BUUUUT, поскольку конечный результат на экране тот же, мы, программисты высокого уровня, обычно не должны знать эти различия. Графический процессор.

Ну, в тех редких случаях, когда вы выполняете очень сложные операции с матрицами, а результаты не то, что вы ожидали, или производительность ужасная, и вам нужно глубоко понять эти методы, чтобы исправить ваш код, ну, тогда документация на Android не может быть В любом случае, помощь. Вместо этого хорошая книга Линейной алгебры была бы вашим лучшим другом. 😉

Холст имеет матричный стек, и вы можете использовать его с помощью методов:

Canvas.save ()

Doc: / ** * Сохраняет текущую матрицу и клип в отдельном стеке. *

* Последующие вызовы для перевода, масштабирования, поворота, перекоса, concat или clipRect, * clipPath будет работать как обычно, но когда балансировочный вызов функции * restore () будет выполнен, эти вызовы будут забыты, а настройки, которые * существовали до Save () будет восстановлен. * * @return Значение для перехода к restoreToCount () для баланса этого сохранения () * /

Canvas.restore ()

Doc: / ** * Этот вызов уравновешивает предыдущий вызов save () и используется для удаления всех * модификаций состояния матрицы / клипа со времени последнего вызова сохранения. * * * * * * * * * * * * * * * * * * * * * * * * * *. * /

Пример: пользовательский вид (Android), который выглядит как поворотная ручка (например, потенциометр)

 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); viewX = getWidth(); //views width viewY = getHeight(); //views height setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); //a must call for every custom view } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); double tempAngel = 3.6 * barValue; int deltaX = bitmap.getWidth() / 2; int deltaY = bitmap.getHeight() / 2; ... canvas.save(); canvas.translate(viewX / 2, viewY / 2); //translate drawing point to center canvas.rotate((float) tempAngel); //rotate matrix canvas.save(); //save matrix. your drawing point is still at (viewX / 2, viewY / 2) canvas.translate(deltaX * -1, deltaY * -1); //translate drawing point a bit up and left to draw the bitmap in the middle canvas.drawBitmap(bitmap, 0,0, bitmapPaint); // draw bitmap to the tranlated point at 0,0 canvas.restore(); //must calls... canvas.restore(); } 

См. Следующий код, похоже, работает. В вашем коде вы определяете матрицу как m, но ссылаясь на нее как на матрицу

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

Если вы столкнулись с проблемой OutOfMemory с приведенными выше ответами, чем использование ниже:

 Bitmap MyFinalBitmap = Bitmap.createBitmap(CurrentBitmap, 0, 0,CurrentBitmap.getWidth()/2, CurrentBitmap.getHeight()/2,matrix, true);