Canvas ImageView 上的矩形问题
Canvas rect issue on ImageView
我在使用 canvas 将照片图像设置到自定义 ImageView 时遇到问题。
我写道:
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)
}
}
MyPhotoView在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(...) 显示(见红框位置):canvas starting point matched with image - (a1) applied
我只是将 (a1) 替换为 (a2),其余代码没有任何更改。
setImage(...) 显示(见红框位置):canvas starting point matched with parent - (a2) applied
我知道 (a1) 用过 deprecated api。所以我用 (a2) 替换了 (a1),但结果不是我预期的那样。
如何在不使用 deprecated api 的情况下使 canvas 矩形与图像矩形完全吻合,结果类似于案例 (a1)?
奇怪的是 (a1) 在 GalaxyS8 + Pie(Android 9.0) 与 GalaxyS21 + Red 上产生不同的结果天鹅绒蛋糕(Android 11).这里我描述了基于后者的结果。无论应用 (a1) 还是 (a2),前一个模型 (GalaxyS8) 的行为都像 (a2)。我也不知道为什么。
那么,如何从此代码中删除设备相关的影响?
我想我找到了解决办法。
只需在ConstraintLayout
的MyPhotoView中添加next属性
android:adjustViewBounds="true"
and (a2) 导致完美拟合图像 rect <-> canvas rect
我在使用 canvas 将照片图像设置到自定义 ImageView 时遇到问题。
我写道:
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)
}
}
MyPhotoView在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(...) 显示(见红框位置):canvas starting point matched with image - (a1) applied
我只是将 (a1) 替换为 (a2),其余代码没有任何更改。
setImage(...) 显示(见红框位置):canvas starting point matched with parent - (a2) applied
我知道 (a1) 用过 deprecated api。所以我用 (a2) 替换了 (a1),但结果不是我预期的那样。
如何在不使用 deprecated api 的情况下使 canvas 矩形与图像矩形完全吻合,结果类似于案例 (a1)?
奇怪的是 (a1) 在 GalaxyS8 + Pie(Android 9.0) 与 GalaxyS21 + Red 上产生不同的结果天鹅绒蛋糕(Android 11).这里我描述了基于后者的结果。无论应用 (a1) 还是 (a2),前一个模型 (GalaxyS8) 的行为都像 (a2)。我也不知道为什么。
那么,如何从此代码中删除设备相关的影响?
我想我找到了解决办法。
只需在ConstraintLayout
的MyPhotoView中添加next属性android:adjustViewBounds="true"
and (a2) 导致完美拟合图像 rect <-> canvas rect