Search code examples
androidcanvasimageviewandroid-camera

Canvas rect issue on ImageView


I have an issue that setting photo images into the custom ImageView with canvas.

I wrote :

public class MyPhotoView extends androidx.appcompat.widget.AppCompatImageView /* ImageView makes no differences */ {
    ...
    public void setImage(final String imageFile) {
        
        // Read rotation value from exif info
        ...
        
        Bitmap bm = BitmapFactory.decodeFile(imageFile);

        if (rotation != 0) {
            Matrix matrix = new Matrix();
            matrix.postRotate(rotation, bm.getWidth()/2, bm.getHeight()/2);
            bm = Bitmap.createBitmap(
                bm , 0, 0, bm.getWidth(), bm.getHeight(), matrix, true
            );
        }

        setImageDrawable(new BitmapDrawable(bm)); // <-- (a1)
        // setImageDrawable(new BitmapDrawable(getResources(), bm)); <-- (a2)
    }
    ... 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.FILL);
    
        canvas.drawRect(0, 0, 100, 100, paint); // <-- (b) draw a red box at (0, 0)
    }
}

the layout of MyPhotoView in ConstraintLayout

...
    <com.sample.myapp.MyPhotoView
        android:id="@+id/result_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
...

setImage(...) showing (See the red box position) : canvas starting point matched with image - (a1) applied

and I just replaced (a1) with (a2) without any changes rest of the code.

setImage(...) showing (See the red box position) : canvas starting point matched with parent - (a2) applied


I know (a1) used deprecated api. So I replaced (a1) with (a2), but it caused not what I expected.

  1. How can I achieve making canvas rect fit exactly with image rect, result like case (a1), without using deprecated api?

  2. It's weird that (a1) produces different results on GalaxyS8 + Pie(Android 9.0) vs GalaxyS21 + Red Velvet Cake(Android 11). Here I described results based on the latter. The former model (GalaxyS8) behaves like (a2) regardless of applying (a1) or (a2). And I don't know why.
    So, How can I remove device dependant effect from this code?


Solution

  • I think I found a solution.

    Just add next property to MyPhotoView in ConstraintLayout

    android:adjustViewBounds="true"
    

    and (a2) causes perfect fit image rect <-> canvas rect