Android: หมุนภาพในมุมมองภาพโดยมุม


154

ฉันใช้รหัสต่อไปนี้เพื่อหมุนภาพใน 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);

6
PS สำหรับปี 2014 ดูเหมือนว่าคุณสามารถตั้งค่า "การหมุน" ใน XML ใน Android Studio ได้ (คุณสามารถแม้เพียงแค่คลิกที่ปุ่ม "คุณสมบัติผู้เชี่ยวชาญ" ด้านขวาถ้าคุณไม่สามารถจะใส่ใจใช้ 'ข้อความ' รูปแบบ!)
Fattie

ค้นหาคำตอบได้ที่นี่ stackoverflow.com/a/52983423/5872337
Geet Thakur

คำตอบ:


194

อีกวิธีง่ายๆในการหมุนImageView:
UPDATE:
การนำเข้าที่ต้องการ:

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บนontouchที่รันไทม์คุณสามารถตั้งค่าonTouchListenerบนImageViewและหมุนได้โดยการเพิ่มสองบรรทัดสุดท้าย (เช่นpostRotateเมทริกซ์และวางมันลงบนIMAGE ดู ) ในส่วนโค้ดข้างต้นในการติดต่อฟังของคุณACTION_MOVEส่วนหนึ่ง


109
เพื่อความสมบูรณ์นี่คือบรรทัดตามImageViewค่าของ:matrix.postRotate( 180f, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
Stefan Hoth

2
วิธีการหมุนภาพในทุกเหตุการณ์ที่สัมผัส?
Saurabh

14
สำหรับฉันถ้าหมุนในรูปแบบสัมพัทธ์เค้าโครงภาพจะเติบโตตามขนาดของภาพที่บรรจุอยู่ ใครบ้างมีประสบการณ์วิธีแก้ปัญหานี้หรือไม่?
Makibo

7
หมายเหตุ: สำหรับการทำงานคุณจะต้องตั้งค่าของคุณImageView's srcแอตทริบิวต์ getDrawable()กำลังจะกลับ null สำหรับฉันจนกว่าฉันรู้ว่าฉันได้ตั้งค่าImageViewของแอตทริบิวต์แทนbackground facepalmsrc
Gary S.

1
มันหมุนภาพในมุมมองภาพเท่านั้น ฉันควรทำอย่างไรเพื่อหมุนภาพตัวเองด้วย?
Ege

177

mImageView.setRotation(angle) ด้วย API> = 11


3
มันจะเปลี่ยนความกว้างและความสูงของมุมมองเป็นขนาดที่ถูกต้องหรือไม่ หรือมีการเปลี่ยนแปลงเพียงว่ามันมีลักษณะอย่างไร
นักพัฒนา android

5
มีวิธีในการ "หมุนภาพเคลื่อนไหว" ในขณะหมุนหรือไม่
Ivan Morgillo

13
@IvanMorgillo คุณสามารถดูได้ViewPropertyAnimatorซึ่งใช้เช่นaView.animate().rotation(20).start()
Jokester

5
@IvanMorgillo: rotationBy()ใช้ ตัวอย่างเช่นview.animate().rotationBy(180f).start(). แต่มันจะกลายเป็นปัญหาหากมีการคลิกมุมมองอย่างต่อเนื่อง
Mangesh

ฉันใช้รหัสนี้ในปุ่มเดียว การคลิกครั้งแรกนั้นใช้ได้ แต่การคลิกครั้งต่อไปจะไม่หมุนอีกต่อไป ฉันควรใส่บรรทัดอื่นเพื่อแก้ไขปัญหานี้หรือไม่?
Eggakin Baconwalker

73

หากคุณสนับสนุน API 11 หรือสูงกว่าคุณสามารถใช้แอตทริบิวต์ XML ต่อไปนี้:

android:rotation="90"

อาจแสดงไม่ถูกต้องในหน้าตัวอย่างของ Studio Studio xml แต่ทำงานได้ตามที่คาดไว้


3
คำแนะนำเกี่ยวกับการแสดงตัวอย่างของ xml ช่วยฉันได้มาก
ngu

ตัวอย่าง XML แสดงสำหรับฉันอย่างถูกต้องหลังจากใช้การหมุนแล้ว
Dick Lucas

สิ่งนี้จะหมุนมุมมอง แต่ไม่ใช่ภาพ! สิ่งนี้จะเพิ่มพื้นที่ว่างข้างภาพ เพียงเพิ่ม a backgroundเพื่อดูเอฟเฟกต์
YBrush

43

มีสองวิธีในการทำเช่นนี้:

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

danx .. แต่มันเป็นวิธีการทำ RotateAnimation ในมุมมองแบบไดนามิก .. ฉันหมายถึงการตั้งค่ามุม d แบบไดนามิก ..
rijinrv

ใช้งานได้ดีกว่าคำตอบที่ยอมรับถ้ารูปภาพที่คุณต้องการหมุนอยู่ใน ListView
Daren

9

ฉันรู้ว่ามันสายไปอย่างบ้าคลั่ง แต่มันมีประโยชน์สำหรับฉันดังนั้นมันอาจช่วยคนอื่นได้

ในฐานะของ API 11 คุณสามารถตั้งค่าการหมุนแบบสัมบูรณ์ของ ImageView โดยทางโปรแกรมโดยใช้ imageView.setRotation(angleInDegrees);วิธีการ

โดยสัมบูรณ์ฉันหมายความว่าคุณสามารถเรียกใช้ฟังก์ชันนี้ซ้ำ ๆ ได้โดยไม่ต้องติดตามการหมุนปัจจุบัน ความหมายถ้าฉันหมุนโดยผ่าน15FไปยังsetRotation()วิธีการแล้วเรียกsetRotation()อีกครั้งด้วย30Fการหมุนของภาพที่มี 30 องศาไม่ใช่ 45 องศา

หมายเหตุ:ใช้งานได้กับคลาสย่อยใด ๆ ของวัตถุมุมมองไม่ใช่เฉพาะ ImageView


ภาพของฉันที่หมุนได้สูงขึ้นตามธรรมชาติเล็กน้อยบนหน้าเว็บ ฉันจะตั้งมันลงได้อย่างไร
ฉันอยากรู้

ภาพของคุณอยู่กึ่งกลางอย่างถูกต้องหรือไม่ หากคุณมีความโปร่งใสไม่สม่ำเสมอในภาพการหมุนอาจทำให้ตำแหน่งเปลี่ยนไปเมื่อหมุน
thomaspsk

ไม่มีมนุษย์คนใดเมื่อภาพหมุนแล้วมันก็ใช้แกน ลองนึกภาพโทรศัพท์มือถือของคุณในแนวตั้งในมือของคุณตอนนี้หมุนเป็นแนวนอน มันไม่ได้สัมผัสมือของคุณอีกต่อไป มีพื้นที่ ... แต่ฉันแก้ไขมันโดยใช้ setPivotX ()
ฉันอยากรู้

5

นี่คือการใช้งาน RotatableImageView ของฉัน การใช้งานนั้นง่ายมากเพียงแค่คัดลอกattrs.xmlและRotatableImageView.javaลงในโครงการของคุณและเพิ่ม RotatableImageView ในเค้าโครงของคุณ ตั้งค่ามุมการหมุนที่ต้องการโดยใช้ตัวอย่าง:พารามิเตอร์มุม

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:example="http://schemas.android.com/apk/res/com.example"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.example.views.RotatableImageView
        android:id="@+id/layout_example_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:src="@drawable/ic_layout_arrow"
        example:angle="180" />
</FrameLayout>

หากคุณมีปัญหาในการแสดงภาพให้ลองเปลี่ยนรหัสในวิธีRotatableImageView.onDraw ()หรือใช้วิธีการ draw () แทน


1
มีประโยชน์มาก ขอบคุณสำหรับการแบ่งปัน!
Stefan Hoth

ฉันได้รับ NullPointerException ขณะใช้งาน RotatableImageView โมฆะป้องกัน onMeasure (int widthMeasureSpec, height heightMeasureSpec int) {int w = getDrawable (). getIntrinsicWidth (); ... } BTW ฉันใช้มันในรหัส (และมีภาพเริ่มต้นที่กำหนด) ไม่ใช่ xml
RRTW

imageView นี้มีปัญหาแปลก ๆ เมื่อใช้งานใน gridView มันทำให้มองไม่เห็นจนกว่าคุณจะเลื่อน
นักพัฒนา android


3

นอกจากนี้ถ้าคุณต้องการที่จะหมุน ImageView โดย180 องศาในแนวตั้งหรือแนวนอนคุณสามารถใช้scaleYหรือสมบัติและการตั้งค่าให้scaleX -1fนี่คือตัวอย่าง Kotlin:

imageView.scaleY = -1f
imageView.scaleX = -1f

1f value ใช้เพื่อส่งคืน ImageView กลับสู่สถานะปกติ:

imageView.scaleY = 1f
imageView.scaleX = 1f

2

ฉันมีทางออกสำหรับสิ่งนี้ ที่จริงแล้วมันเป็นวิธีการแก้ปัญหาที่เกิดขึ้นหลังจากการหมุน (ภาพสี่เหลี่ยมไม่เหมาะกับ ImagView) แต่มันครอบคลุมปัญหาของคุณด้วย .. ถึงแม้ว่าวิธีนี้จะมีภาพเคลื่อนไหวให้ดีขึ้นหรือแย่ลง

    int h,w;
    Boolean safe=true;

การรับพารามิเตอร์ของ imageView เป็นไปไม่ได้เมื่อเริ่มต้นกิจกรรมการทำเช่นนั้นโปรดอ้างอิงถึงวิธีการแก้ปัญหา นี้หรือกำหนดขนาดที่ on คลิกที่ปุ่มแบบนี้

    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 แม้ว่ามันจะไม่จำเป็น (เมื่อความสูงมีขนาดเล็กกว่าความกว้าง) หากมันรบกวนคุณคุณสามารถเพิ่มผู้ประกอบการแบบไตรภาคภายใน X / scaleY


2

ฉันคิดว่าวิธีที่ดีที่สุด :)

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

2

หมุนรูปภาพใน Android ด้วยความล่าช้า:

imgSplash.animate().rotationBy(360f).setDuration(3000).setInterpolator(new LinearInterpolator()).start();

1

ลองทำดูในมุมมองที่กำหนดเอง

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


1

นี่เป็นทางออกที่ดีสำหรับการวาง 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 ที่ฉันทำไว้ที่นี่


1

หากคุณต้องการหมุนมุมมองด้วยสายตาเท่านั้นคุณสามารถใช้:

iv.setRotation(float)

1

สำหรับ Kotlin

mImageView.rotation = 90f //angle in float

สิ่งนี้จะหมุน imageView แทนที่จะหมุนภาพ

นอกจากนี้แม้ว่ามันจะเป็นวิธีการในViewชั้นเรียน ดังนั้นคุณสามารถหมุนมุมมองใดก็ได้โดยใช้มัน


0

น่าเศร้าที่ฉันไม่คิดว่าจะมี Matrixระดับเป็นผู้รับผิดชอบทั้งหมด manipulations ภาพไม่ว่าจะหมุนหดตัว / การเจริญเติบโตบิดเบือน ฯลฯ

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

ฉันขอโทษ แต่ฉันไม่สามารถคิดถึงทางเลือกอื่นได้ บางทีคนอื่นอาจจะสามารถทำได้ แต่เวลาที่ฉันต้องจัดการกับภาพที่ฉันใช้เป็นเมทริกซ์

ขอให้โชคดี!


0

อีกวิธีหนึ่งที่เป็นไปได้คือการสร้างมุมมองรูปภาพที่กำหนดเอง (พูดRotateableImageView extends ImageView) ... และแทนที่ onDraw () เพื่อหมุน canvas / bitmaps ก่อนที่จะทำการ red แดงไปที่ canvas อย่าลืมที่จะคืนค่า canvas

แต่ถ้าคุณจะหมุนเพียงครั้งเดียวของการดูภาพการแก้ปัญหาของคุณควรจะดีพอ


0

ไม่มีเมทริกซ์และภาพเคลื่อนไหว:

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

0

เพียงแค่เขียนสิ่งนี้ในกิจกรรมของคุณ Result

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

0

ลองใช้รหัสนี้ทำงานได้ 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);
            }
        }

0

แทนที่จะแปลงภาพเป็นบิตแมปแล้วหมุนลองหมุนมุมมองภาพโดยตรงเช่นรหัสด้านล่าง

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

0

ทำตามคำตอบด้านล่างเพื่อหมุนมุมมองภาพอย่างต่อเนื่อง

int i=0;

หากคลิกปุ่มหมุน

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

0

หากคุณต้องการหมุนภาพ 180 องศาจากนั้นใส่ค่าทั้งสองนี้ในแท็ก imageview: -

android:scaleX="-1"
android:scaleY="-1"

คำอธิบาย: - scaleX = 1 และ scaleY = 1 แสดงว่าเป็นสภาวะปกติ แต่ถ้าเราใส่ -1 ในคุณสมบัติ scaleX / scaleY มันจะหมุน 180 องศา


0
Matrix matrix = new Matrix();
imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
matrix.postRotate((float) 20, imageView.getDrawable().getBounds().width()/2, imageView.getDrawable().getBounds().height()/2);
imageView.setImageMatrix(matrix);

วิธีใช้?

public class MainActivity extends AppCompatActivity {
   int view = R.layout.activity_main;
   TextView textChanger;
   ImageView imageView;
   @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(view);
      textChanger = findViewById(R.id.textChanger);
      imageView=findViewById(R.id.imageView);
      textChanger.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            roateImage(imageView);
         }
      });
   }
   private void roateImage(ImageView imageView) {
      Matrix matrix = new Matrix();
      imageView.setScaleType(ImageView.ScaleType.MATRIX); //required
      matrix.postRotate((float) 20, imageView.getDrawable().getBounds().width()/2,    imageView.getDrawable().getBounds().height()/2);
      imageView.setImageMatrix(matrix);
   }
}

0

คุณสามารถใช้คุณสมบัติการหมุนของ ImageView

ด้านล่างนี้เป็นคุณลักษณะจาก ImageView พร้อมรายละเอียดจากแหล่ง Android

<!-- rotation of the view, in degrees. -->
<attr name="rotation" format="float" />
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.