Android: поворот изображения в imageview на угол


Я использую следующий код, чтобы повернуть изображение в ImageView на угол. Есть ли какой-либо более простой и менее сложный метод.

ImageView iv = (ImageView)findViewById(imageviewid);
TextView tv = (TextView)findViewById(txtViewsid);
Matrix mat = new Matrix();
Bitmap bMap = BitmapFactory.decodeResource(getResources(),imageid);
mat.postRotate(Integer.parseInt(degree));===>angle to be rotated
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,bMap.getWidth(),bMap.getHeight(), mat, true);
iv.setImageBitmap(bMapRotate);
18 126

18 ответов:

еще один простой способ повернуть ImageView:
обновление:
Необходимого импорта, так:

import android.graphics.Matrix;
import android.widget.ImageView;

Код: (Если imageView,angle,pivotX & pivotY уже определены)

Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX);   //required
matrix.postRotate((float) angle, pivotX, pivotY);
imageView.setImageMatrix(matrix);

этот метод не требует создания нового растрового изображения каждый раз.

Примечание: чтобы повернуть ImageView on ontouch во время выполнения вы можете набор onTouchListener on ImageView & поверните его, добавив последний два линии(т. е. postRotate матрицу и установить его на imageView) в приведенном выше коде раздел в вашем сенсорном прослушивателе ACTION_MOVE часть.

mImageView.setRotation(angle) с API>=11

Если вы поддерживаете API 11 или выше, вы можете просто использовать следующий атрибут XML:

android:rotation="90"

Он может не отображаться правильно в Android Studio xml preview, но он работает так, как ожидалось.

есть два способа сделать это:

1, Используя Matrix для создания нового растрового изображения:

imageView = (ImageView) findViewById(R.id.imageView);
Bitmap myImg = BitmapFactory.decodeResource(getResources(), R.drawable.image);

Matrix matrix = new Matrix();
matrix.postRotate(30);

Bitmap rotated = Bitmap.createBitmap(myImg, 0, 0, myImg.getWidth(), myImg.getHeight(),
        matrix, true);

imageView.setImageBitmap(rotated);

2 использовать RotateAnimation на View вы хотите повернуть, и убедитесь, что анимация для fillAfter=true,duration=0 и fromDegrees=toDgrees

 <?xml version="1.0" encoding="utf-8"?>
<rotate
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:fromDegrees="45"
  android:toDegrees="45"
  android:pivotX="50%"
  android:pivotY="50%"
  android:duration="0"
  android:startOffset="0"
/>

и надуть анимацию в коде:

Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotation);
myView.startAnimation(rotation);

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

начиная с API 11, вы можете установить абсолютное вращение ImageView программно с помощью imageView.setRotation(angleInDegrees); метод.

по абсолютному, я имею в виду, что вы можете повторно вызвать эту функцию без необходимости отслеживать текущее вращение. То есть, если я вращаюсь, передавая 15F до setRotation() метод, а затем вызвать setRotation() снова 30F вращение изображения с быть 30 градусов, не 45 градусов.

Примечание: это на самом деле работает для любого подкласса View объект, а не только ImageView.

Это мой реализация RotatableImageView. Использование очень просто: Просто скопируйте attrs.xml и RotatableImageView.java в ваш проект и добавить RotatableImageView к макету. Установите нужный угол поворота с помощью пример:угол

попробуйте это на пользовательском представлении

public class DrawView extends View {


    public DrawView(Context context,AttributeSet attributeSet){
        super(context, attributeSet);
    }

    @Override
    public void onDraw(Canvas canvas) {
        /*Canvas c=new Canvas(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1)    );

        c.rotate(45);*/

        canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.new_minute1), 0, 0, null);
        canvas.rotate(45);
    }
}

вот хорошее решение для размещения повернутого drawable для imageView:

Drawable getRotateDrawable(final Bitmap b, final float angle) {
    final BitmapDrawable drawable = new BitmapDrawable(getResources(), b) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, b.getWidth() / 2, b.getHeight() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
    return drawable;
}

использование:

Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);

другой вариант:

private Drawable getRotateDrawable(final Drawable d, final float angle) {
    final Drawable[] arD = { d };
    return new LayerDrawable(arD) {
        @Override
        public void draw(final Canvas canvas) {
            canvas.save();
            canvas.rotate(angle, d.getBounds().width() / 2, d.getBounds().height() / 2);
            super.draw(canvas);
            canvas.restore();
        }
    };
}

кроме того, если вы хотите повернуть растровое изображение, но боитесь OOM, вы можете использовать решение NDK, которое я сделал здесь

просто напишите это в вашем onactivityResult

            Bitmap yourSelectedImage= BitmapFactory.decodeFile(filePath);
            Matrix mat = new Matrix();
            mat.postRotate((270)); //degree how much you rotate i rotate 270
            Bitmap bMapRotate=Bitmap.createBitmap(yourSelectedImage, 0,0,yourSelectedImage.getWidth(),yourSelectedImage.getHeight(), mat, true);
            image.setImageBitmap(bMapRotate);
            Drawable d=new BitmapDrawable(yourSelectedImage);
            image.setBackground(d); 

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

    int h,w;
    Boolean safe=true;

получение параметров imageView невозможно при инициализации активности Для этого, пожалуйста, обратитесь к этому решение или установите размеры в onClick кнопки, как это

    rotateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            if(imageView.getRotation()/90%2==0){
                h=imageView.getHeight();
                w=imageView.getWidth();

            }
        .
        .//Insert the code Snippet below here 
       }

и код для запуска, когда мы хотим повернуть ImageView

if(safe)     
imageView.animate().rotationBy(90).scaleX(imageView.getRotation()/90%2==0?(w*1.0f/h):1).scaleY(imageView.getRotation()/90%2==0?(w*1.0f/h):1).setDuration(2000).setInterpolator(new LinearInterpolator()).setListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {
                      safe=false;
                }

                @Override
                public void onAnimationEnd(Animator animation) {
                      safe=true;

                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            }).start();
        }
    });

этого решения достаточно для решения проблемы выше.Хотя он будет сжимать imageView, даже если это не нужно(когда высота меньше ширины).Если это вас беспокоит, вы можете добавить еще один тернарный оператор внутри scaleX/scaleY.

Я думаю, что лучший способ :)

int angle = 0;
imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            angle = angle + 90;
            imageView.setRotation(angle);
        }
    });

к сожалению, я не думаю, что есть. Элемент Matrix класс отвечает за все манипуляции с изображением, будь то вращение, сжатие/рост, перекос и т. д.

http://developer.android.com/reference/android/graphics/Matrix.html

еще одно возможное решение-создать свой собственный вид изображения (скажем RotateableImageView extends ImageView)...и переопределите onDraw (), чтобы повернуть либо холст/растровые изображения перед повторным переходом на холст.Не забудьте восстановить холст обратно.

но если вы собираетесь повернуть только один экземпляр изображения,ваше решение должно быть достаточно хорошим.

без матрицы и анимированные:

{
    img_view = (ImageView) findViewById(R.id.imageView);
    rotate = new RotateAnimation(0 ,300);
    rotate.setDuration(500);
    img_view.startAnimation(rotate);
}

попробуйте этот код 100% рабочий;

на кнопку поворота нажмите написать этот код:

        @Override
        public void onClick(View view) {
            if(bitmap==null){
                Toast.makeText(getApplicationContext(), "Image photo is not yet set", Toast.LENGTH_LONG).show();
            }
            else {
                Matrix matrix = new Matrix();
                ivImageProduct.setScaleType(ImageView.ScaleType.MATRIX);   //required
                matrix.postRotate(90,ivImageProduct.getDrawable().getBounds().width()/2,ivImageProduct.getDrawable().getBounds().height()/2);
                Bitmap bmp=Bitmap.createBitmap(bitmap, 0, 0,bitmap.getWidth(), bitmap.getHeight(), matrix, true);
                bitmap.recycle();
                bitmap=bmp;
                ivImageProduct.setImageBitmap(bitmap);
            }
        }

Если вы хотите только повернуть вид визуально вы можете использовать:

iv.setRotation(float)

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

ImageView myImageView = (ImageView)findViewById(R.id.my_imageview);

AnimationSet animSet = new AnimationSet(true);
animSet.setInterpolator(new DecelerateInterpolator());
animSet.setFillAfter(true);
animSet.setFillEnabled(true);

final RotateAnimation animRotate = new RotateAnimation(0.0f, -90.0f,
    RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
    RotateAnimation.RELATIVE_TO_SELF, 0.5f);

animRotate.setDuration(1500);
animRotate.setFillAfter(true);
animSet.addAnimation(animRotate);

myImageView.startAnimation(animSet);

следуйте приведенному ниже ответу для непрерывного вращения imageview

int i=0;

если кнопка поворота нажата

imageView.setRotation(i+90);
i=i+90;