【发布时间】:2018-07-17 09:42:09
【问题描述】:
我正在尝试制作一个简单的图像编辑器。一开始我认为将视图状态简单地保存为位图是个好主意,但事实证明,屏幕分辨率范围很广,这会导致巨大的质量(和内存使用)波动。
现在我正在尝试制作一个将视图状态转换为所需分辨率的模块。
在下面的代码中,我试图在画布中重新创建视图的当前状态:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.id.test_1_1);
bitmap = Bitmap.createScaledBitmap(bitmap, parentView.getMeasuredWidth(), parentView.getMeasuredHeight(), true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
for (View rootView : addedViews) {
ImageView imageView = rootView.findViewById(R.id.sticker);
float[] viewPosition = new float[2];
transformToAncestor(viewPosition, parentView, imageView);
Bitmap originalBitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
Matrix adjustMatrix = new Matrix();
adjustMatrix.postTranslate(viewPosition[0], viewPosition[1]);
adjustMatrix.postScale(
rootView.getScaleX(),
rootView.getScaleY(),
rootView.getWidth() / 2,
rootView.getHeight() / 2);
adjustMatrix.postRotate(rootView.getRotation(),
rootView.getWidth() / 2,
rootView.getHeight() / 2);
canvas.drawBitmap(originalBitmap, adjustMatrix, paint);
}
transformToAncestor 函数来自here。
public static void transformToAncestor(float[] point, final View ancestor, final View descendant) {
final float scrollX = descendant.getScrollX();
final float scrollY = descendant.getScrollY();
final float left = descendant.getLeft();
final float top = descendant.getTop();
final float px = descendant.getPivotX();
final float py = descendant.getPivotY();
final float tx = descendant.getTranslationX();
final float ty = descendant.getTranslationY();
final float sx = descendant.getScaleX();
final float sy = descendant.getScaleY();
point[0] = left + px + (point[0] - px) * sx + tx - scrollX;
point[1] = top + py + (point[1] - py) * sy + ty - scrollY;
ViewParent parent = descendant.getParent();
if (descendant != ancestor && parent != ancestor && parent instanceof View) {
transformToAncestor(point, ancestor, (View) parent);
}
}
(作者写了一个说明,他的函数不支持旋转,但在我的示例中没有太多旋转,所以我认为现在不重要)。
我的问题是:
第一张图片是通过保存父视图状态生成的。第二个是通过将视图位置、旋转和缩放转换到画布上生成的。 如您所见,在画布上,未缩放的贴纸位置正确,但缩放后的位置不正确。
如何正确定位这些缩放视图?
【问题讨论】:
-
你需要什么
transformToAncestor方法?您的目标是创建某种图层(在您的情况下用白星绘制) - 每个图层都缩放、平移和可能旋转? -
我正在使用这种方法来转换每个星星的位置,然后我正在缩放和旋转它。有一个更好的方法吗?我的目标是根据视图位置渲染图像,不需要图层。
-
我不明白:您同时使用
ImageViews 和Canvas#drawBitmap,这是为了什么?只需使用自定义视图和Canvas#drawBitmap,您就可以控制一切,几乎不需要额外的逻辑 -
就我个人而言,我会分叉该库并删除它使用的任何
ImageViews 并替换为原始的低级别Bitmaps - 如果您想同时使用它们,您将永远无法获得像素完美的解决方案
标签: android scale android-canvas android-view android-bitmap