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 ответов
еще один простой способ повернуть 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 во время выполнения вы можете set onTouchListener onImageView
& повернуть его, добавив последний два строки (т. е. postRotate матрицу и установить его на imageView) в приведенном выше коде раздел в вашем сенсорном прослушивателе ACTION_MOVE часть.
Если вы поддерживаете 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 градусов.
Примечание: это действительно работает для любого подкласса посмотреть объект, а не только 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);
}
});
к сожалению, я не думаю, что есть. The 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);
}
}
вместо того, чтобы конвертировать изображение в растровое изображение, а затем повернуть его попробуйте повернуть прямой вид изображения, как показано ниже кода.
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;