Матрица просмотра изображений для Android + переводить

Я пытаюсь вручную получить изображение внутри изображения с центром и подгонять экран. Мне нужно сделать это с помощью матрицы (позже я буду динамически менять матричное преобразование).

Проблема в том, что я не могу получить изображение с центром в представлении (масштаб подходит). Вот код:

// Compute the scale to choose (this works) float scaleX = (float) displayWidth / (float) imageWidth; float scaleY = (float) displayHeight / (float) imageHeight; float minScale = Math.min(scaleX, scaleY); // tx, ty should be the translation to take the image back to the screen center float tx = Math.max(0, 0.5f * ((float) displayWidth - (minScale * imageWidth))); float ty = Math.max(0, 0.5f * ((float) displayHeight - (minScale * imageHeight))); // Compute the matrix Matrix m = new Matrix(); m.reset(); // Middle of the image should be the scale pivot m.postScale(minScale, imageWidth/2, imageHeight/2); // Translate m.postTranslate(tx, ty); imageView.setImageMatrix(m); 

Вышеприведенный код работает, если я не центрирую масштаб в центре изображения (но мне нужно будет сделать это позже, поэтому мне нужно выяснить формулу сейчас).

Я думал, что следующий вопрос исправит проблему, но изображение по-прежнему смещено (вниз и вправо).

 tx += 0.5*imageWidth*minScale; ty += 0.5*imageHeight*minScale; 

Некоторые значения у меня: – изображение: 200×133 – дисплей: 800×480 – minScale: 2.4 – последний верхний левый угол изображения: 100, 67 (должно быть 17, 0)

Solutions Collecting From Web of "Матрица просмотра изображений для Android + переводить"

Существует удобный метод Matrix.setRectToRect (RectF, RectF, ScaleToFit), который поможет вам здесь.

 Matrix m = imageView.getImageMatrix(); RectF drawableRect = new RectF(0, 0, imageWidth, imageHeight); RectF viewRect = new RectF(0, 0, imageView.getWidth(), imageView.getHeight()); m.setRectToRect(drawableRect, viewRect, Matrix.ScaleToFit.CENTER); imageView.setImageMatrix(m); 

Это должно привести к тому, что матрица m будет иметь комбинацию масштабирования и преобразования значений, которые необходимы для отображения центрированного по размеру и подгонки внутри виджета ImageView.

Вот как я решил свою проблему с помощью матриц (запрошенных joakime в другом ответе):

 private void setImageTransformation(float tx, float ty, float scale) { savedMatrix.reset(); savedMatrix.postTranslate(-imageWidth / 2f, -imageHeight / 2f); savedMatrix.postScale(scale, scale); savedMatrix.postTranslate(tx, ty); imageView.setImageMatrix(savedMatrix); } public void resetImageMatrix() { if (!isImageLoaded()) return; imageWidth = imageView.getDrawable().getIntrinsicWidth(); imageHeight = imageView.getDrawable().getIntrinsicHeight(); float scaleX = (float) displayWidth / (float) imageWidth; float scaleY = (float) displayHeight / (float) imageHeight; minScale = Math.min(scaleX, scaleY); maxScale = 2.5f * minScale; initialTranslation.set( Math.max(0, minScale * imageWidth / 2f + 0.5f * (displayWidth - (minScale * imageWidth))), Math.max(0, minScale * imageHeight / 2f + 0.5f * (displayHeight - (minScale * imageHeight)))); currentScale = minScale; currentTranslation.set(initialTranslation); initialImageRect.set(0, 0, imageWidth, imageHeight); setImageTransformation(initialTranslation.x, initialTranslation.y, minScale); } 

Я немного обманываю здесь, потому что пинч не находится по центру между пальцами пользователя, что приемлемо в моем случае.

Эй, у меня была такая же проблема, и ты был так близок! Это был порядок операций, по крайней мере для меня. Следующие работали для меня:

 tx = (width - imgWidth) * 0.5f * scale; 

Или используя

  m.postScale(minScale, minScale); //keep aspect ratio float tx = (getWidth() - bitmap1.getWidth()* scale) * 0.5f ; float ty = (getHeight() - bitmap1.getHeight()* scale) * 0.5f ; matrix.postTranslate(tx, ty ); 

Где getWidth – ширина вашего изображения. Прекрасно работает для меня