Her*_*u S 8 java android image imageview
我们正在构建一个涉及图像编辑的Android应用程序.一些功能包括旋转图像和擦除图像的一部分.
我们使用以下库:https://github.com/nimengbo/StickerView
我们已成功创建了一个旋转和擦除图像的功能.但是,当我们尝试执行以下操作时:
我们发现了以下错误:
从上图中,黄线是手指的实际移动(在贴纸上垂直向下).但是,发现擦除的路径是对角的.
此问题仅在旋转图像时存在.图像未旋转时不存在.
经过进一步的调试,我们从上述问题中得出一些假设:
我们怎样才能确保路径仍在参考正确的路径,即使在旋转后手指也会触摸到什么路径?
这是我们在StickerView.java类中扩展ImageView类的代码.
的onTouchEvent
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = MotionEventCompat.getActionMasked(event);
float[] pointXY = new float[2];
pointXY = getAbsolutePosition(event.getX(0),event.getY(0));
float xPoint = pointXY[0];
float yPoint = pointXY[1];
switch (action) {
case MotionEvent.ACTION_DOWN:
// first touch
// if it is inside the image
if (isInBitmap(event)) {
// set isInSide to true
isInSide = true;
// if it is a scratch
if(doScratch){
// start creating the scratch path
mScratchPath = new Path();
mScratchPath.moveTo(xPoint, yPoint);
mScratchPath.lineTo(xPoint, yPoint);
paths.add(new Pair<Path, Paint>(mScratchPath, mScratchCurrentPaint));
}
}
break;
case MotionEvent.ACTION_MOVE:
// if two fingers touch and is not a scratch,
// then it means we can rotate / resize / pan
if (isPointerDown && !doScratch) {
// reset matrix
matrix.reset();
// get the center point
scaledImageCenterX = (mImageWidth * mScaleFactor) / 2 ;
scaledImageCenterY = (mImageHeight * mScaleFactor) / 2;
// ROTATE THE IMAGE !!!
matrix.postRotate(lastRotateDegree, scaledImageCenterX, scaledImageCenterY);
// done to call onDraw
invalidate();
}
break;
}
if (operationListener != null) {
operationListener.onEdit(this);
}
// if it is a scratch
if(doScratch){
// then for every point, create a scratch path
mScratchPath.lineTo(xPoint, yPoint);
invalidate();
}else{
mScaleDetector.onTouchEvent(event);
mRotateDetector.onTouchEvent(event);
mMoveDetector.onTouchEvent(event);
mShoveDetector.onTouchEvent(event);
}
return handled;
}
Run Code Online (Sandbox Code Playgroud)
的onDraw
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// if the image exists
if (mBitmap != null) {
// save canvas
canvas.save();
// if it is a scratch
if(doScratch){
// scratch the image
mFillCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// Draw our surface, nice an pristine
final Drawable surface = mScratchSurface;
if(surface != null) {
surface.draw(mFillCanvas);
}
//Scratch the surface
if(paths != null) {
for (Pair<Path, Paint> p : paths) {
mFillCanvas.drawPath(p.first,p.second);
}
}
mBitmap = mFillCache;
}
canvas.drawBitmap(mBitmap, matrix, bitmapPaint);
canvas.restore();
}
}
Run Code Online (Sandbox Code Playgroud)
getAbsolutePosition函数
public float[] getAbsolutePosition(float Ax, float Ay) {
float[] mMatrixValues = new float[9];
matrix.getValues(mMatrixValues);
float x = mImageWidth - ((mMatrixValues[Matrix.MTRANS_X] - Ax) / mMatrixValues[Matrix.MSCALE_X]) - (mImageWidth - getTranslationX());
float y = mImageHeight - ((mMatrixValues[Matrix.MTRANS_Y] - Ay) / mMatrixValues[Matrix.MSCALE_X]) - (mImageHeight - getTranslationY());
return new float[] { x, y};
}
Run Code Online (Sandbox Code Playgroud)
您需要在坐标上应用旋转矩阵。这里theta是图像旋转的角度。

图片来源维基百科
在代码中它会是这样的
int getAbsoluteX(int x, int y, double theta)
{
int x_new = (int)(x*Math.cos(theta) - y*Math.sin(theta));
return x_new;
}
int getAbsoluteY(int x, int y, double theta)
{
int y_new = (int)(x*Math.sin(theta) + y*Math.cos(theta));
return y_new;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
373 次 |
| 最近记录: |