gpt4 book ai didi

android - 如何放大/缩放图像的一部分

转载 作者:可可西里 更新时间:2023-11-01 19:06:55 26 4
gpt4 key购买 nike

我正在制作一个应用程序,用户可以在其中单击图像的一部分并在 WebView 的一角获得放大版本。我设法制作了一个可以制作缩放版本的 Paint,但它显示了错误的位置,就像有一些偏移一样。

我知道这个问题已被问过很多次并且已经得到回答,但似乎这些解决方案都没有帮助。

这是我使用的代码:

  @Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
zoomPos = new PointF();
zoomPos.x = event.getX();
zoomPos.y = event.getY();


matrix = new Matrix();
mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
outlinePaint = new Paint(Color.BLACK);
outlinePaint.setStyle(Paint.Style.STROKE);

int action = event.getAction();

switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
zooming = true;
this.invalidate();
break;
case MotionEvent.ACTION_UP:
Point1 = true;
zooming = false;
this.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
zooming = false;
this.invalidate();
break;

default:
break;
}



return true;
}

@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
if (zooming) {
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
mPaint.getShader().setLocalMatrix(matrix);


canvas.drawCircle(100, 100, 100, mPaint);

}

}

从技术上讲,它应该在左上角画一个圆圈并显示我手指所在区域的缩放图像,它画了一个圆圈,但同样,缩放比例发生了偏移。

最终结果应该是这样的:

enter image description here

主 Activity .java

public class MainActivity extends Activity {
static ImageView takenPhoto;
static PointF zoomPos;
Paint shaderPaint;
static BitmapShader mShader;
BitmapShader shader;
Bitmap bmp;
static Bitmap mutableBitmap;
static Matrix matrix;
Canvas canvas;
static Paint mPaint;
static Paint Paint;
static boolean zooming;


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/boxes.jpg");

String fileString = file.getPath();
takenPhoto = (ZoomView) findViewById(R.id.imageView1);
bmp = BitmapFactory.decodeFile(fileString);
mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
takenPhoto.setImageBitmap(mutableBitmap);
matrix = new Matrix();
mShader = new BitmapShader(mutableBitmap, TileMode.CLAMP, TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
zoomPos = new PointF();
Paint = new Paint(Color.RED);
}
}

缩放 View .java

public class ZoomView extends ImageView {

private PointF zoomPos;
PointF fingerPos;
private Paint paint = new Paint(Color.BLACK);
boolean zooming;
Matrix matrix;
BitmapShader mShader;
Paint mPaint;
Paint outlinePaint;
boolean Point1;

public ZoomView(Context context) {
super(context);
}

public ZoomView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public ZoomView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
zoomPos = new PointF();
zoomPos.x = event.getX();
zoomPos.y = event.getY();


matrix = new Matrix();
mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
outlinePaint = new Paint(Color.BLACK);
outlinePaint.setStyle(Paint.Style.STROKE);

int action = event.getAction();

switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
zooming = true;
this.invalidate();
break;
case MotionEvent.ACTION_UP:
Point1 = true;
zooming = false;
this.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
zooming = false;
this.invalidate();
break;

default:
break;
}



return true;
}

@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
if (zooming) {
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
mPaint.getShader().setLocalMatrix(matrix);
RectF src = new RectF(zoomPos.x-50, zoomPos.y-50, zoomPos.x+50, zoomPos.y+50);
RectF dst = new RectF(0, 0, 100, 100);
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
matrix.postScale(2f, 2f);
mPaint.getShader().setLocalMatrix(matrix);


canvas.drawCircle(100, 100, 100, mPaint);
canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
canvas.drawCircle(zoomPos.x-110, zoomPos.y-110, 10, outlinePaint);

}
if(Point1){
canvas.drawCircle(zoomPos.x, zoomPos.y, 10, paint);
}
}
}

编辑:

如您所见,新代码要好得多,但仍然存在一些偏移量 - 黑点 - 手指的位置。

enter image description here

最佳答案

问题似乎出在您如何使用矩阵

现在您正在使用原始图像 (1) 作为着色器,然后围绕轴心点 (2) post 放大>,这就像围绕点 (3) 进行缩放 - 但不是以点 (4) 为中心! (例如,打开谷歌地图并用鼠标放大 map - 点围绕枢轴缩放但枢轴未居中)

enter image description here

通过使用 RectRect method 可以更轻松地实现您想要的效果. IE。您想要从原始图像(5) 中取出一小块区域并将其绘制到更大的区域(6)

enter image description here

这是一个代码示例:

RectF src = new RectF(zoomPos.x-50, zoomPos.y-50, zoomPos.x+50, zoomPos.y+50);
RectF dst = new RectF(0, 0, 200, 200);
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);

补充几点:

  • 尽量不要在 onTouch 中创建 new 对象 - 它被调用了很多次并且对性能 不利。相反,创建一次并重复使用。
  • getAction() 当屏幕上有多个手指时会出现问题,因为它是操作 ID 和指针 ID。而是使用 getActionMasked()getActionIndex() .
  • 不要使用硬编码值(示例代码中的 50/100)- 这些是像素,不知道屏幕密度。使用像 dp 这样的缩放尺寸。

关于android - 如何放大/缩放图像的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32055525/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com