gpt4 book ai didi

android - 图像的自定义裁剪无法正常工作

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:03:01 26 4
gpt4 key购买 nike

我正在使用以下代码在 android 中执行图像裁剪。

但是我得到了错误的结果。我得到非常缩放的图片,我认为我的代码有问题

代码:

   package net.londatiga.android;

import java.io.ByteArrayOutputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.drawable.BitmapDrawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;

public class CropView extends ImageView {

Paint paint = new Paint();
private int initial_size = 300;
private static Point leftTop, rightBottom, center, previous;

private static final int DRAG= 0;
private static final int LEFT= 1;
private static final int TOP= 2;
private static final int RIGHT= 3;
private static final int BOTTOM= 4;

private int imageScaledWidth,imageScaledHeight;
// Adding parent class constructors
public CropView(Context context) {
super(context);
initCropView();
}

public CropView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
initCropView();
}

public CropView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initCropView();
}

@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if(leftTop.equals(0, 0))
resetPoints();
canvas.drawRect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y, paint);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
previous.set((int)event.getX(), (int)event.getY());
break;
case MotionEvent.ACTION_MOVE:
if(isActionInsideRectangle(event.getX(), event.getY())) {
adjustRectangle((int)event.getX(), (int)event.getY());
invalidate(); // redraw rectangle
previous.set((int)event.getX(), (int)event.getY());
}
break;
case MotionEvent.ACTION_UP:
previous = new Point();
break;
}
return true;
}

private void initCropView() {
paint.setColor(Color.YELLOW);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(5);
leftTop = new Point();
rightBottom = new Point();
center = new Point();
previous = new Point();
}

public void resetPoints() {
center.set(getWidth()/2, getHeight()/2);
leftTop.set((getWidth()-initial_size)/2,(getHeight()-initial_size)/2);
rightBottom.set(leftTop.x+initial_size, leftTop.y+initial_size);
}

private static boolean isActionInsideRectangle(float x, float y) {
int buffer = 10;
return (x>=(leftTop.x-buffer)&&x<=(rightBottom.x+buffer)&& y>=(leftTop.y-buffer)&&y<=(rightBottom.y+buffer))?true:false;
}

private boolean isInImageRange(PointF point) {
// Get image matrix values and place them in an array
float[] f = new float[9];
getImageMatrix().getValues(f);

// Calculate the scaled dimensions
imageScaledWidth = Math.round(getDrawable().getIntrinsicWidth() * f[Matrix.MSCALE_X]);
imageScaledHeight = Math.round(getDrawable().getIntrinsicHeight() * f[Matrix.MSCALE_Y]);

return (point.x>=(center.x-(imageScaledWidth/2))&&point.x<=(center.x+(imageScaledWidth/2))&&point.y>=(center.y-(imageScaledHeight/2))&&point.y<=(center.y+(imageScaledHeight/2)))?true:false;
}

private void adjustRectangle(int x, int y) {
int movement;
switch(getAffectedSide(x,y)) {
case LEFT:
movement = x-leftTop.x;
if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement)))
leftTop.set(leftTop.x+movement,leftTop.y+movement);
break;
case TOP:
movement = y-leftTop.y;
if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movement)))
leftTop.set(leftTop.x+movement,leftTop.y+movement);
break;
case RIGHT:
movement = x-rightBottom.x;
if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
break;
case BOTTOM:
movement = y-rightBottom.y;
if(isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movement)))
rightBottom.set(rightBottom.x+movement,rightBottom.y+movement);
break;
case DRAG:
movement = x-previous.x;
int movementY = y-previous.y;
if(isInImageRange(new PointF(leftTop.x+movement,leftTop.y+movementY)) && isInImageRange(new PointF(rightBottom.x+movement,rightBottom.y+movementY))) {
leftTop.set(leftTop.x+movement,leftTop.y+movementY);
rightBottom.set(rightBottom.x+movement,rightBottom.y+movementY);
}
break;
}
}

private static int getAffectedSide(float x, float y) {
int buffer = 10;
if(x>=(leftTop.x-buffer)&&x<=(leftTop.x+buffer))
return LEFT;
else if(y>=(leftTop.y-buffer)&&y<=(leftTop.y+buffer))
return TOP;
else if(x>=(rightBottom.x-buffer)&&x<=(rightBottom.x+buffer))
return RIGHT;
else if(y>=(rightBottom.y-buffer)&&y<=(rightBottom.y+buffer))
return BOTTOM;
else
return DRAG;
}

public byte[] getCroppedImage() {
BitmapDrawable drawable = (BitmapDrawable)getDrawable();
float x = leftTop.x-center.x+(drawable.getBitmap().getWidth()/2);
float y = leftTop.y-center.y+(drawable.getBitmap().getHeight()/2);
Bitmap cropped = Bitmap.createBitmap(drawable.getBitmap(),(int)x,(int)y,(int)rightBottom.x-(int)leftTop.x,(int)rightBottom.y-(int)leftTop.y);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
cropped.compress(Bitmap.CompressFormat.PNG, 100, stream);
return stream.toByteArray();
}
}

我尝试裁剪的图像是

enter image description here

预期的图像是矩形框中的图像,但我得到的是非常缩放的图像

结果图片

enter image description here

我该如何解决这个问题,我尝试通过更改一些代码但没有找到任何结果。

另一个问题是,通过使用这个矩形框,我只能裁剪矩形形状的图像,是否有可能以我想要的任何形状裁剪图像。

我在其中一个应用程序(Document Scanner 试用版)中观察到这一点,在该应用程序中,用户可以使用相同的矩形框裁剪一些不规则形状的图像。

我怎样才能达到这个结果?

请推荐

谢谢

最佳答案

我已经实现了 Android Crop Image 图书馆。这对我很有帮助。它具有以下特点。

  1. 双指缩放以裁剪图片的很小一部分
  2. 在图像上可调整大小的矩形
  3. 将高效的图像裁剪结果反馈给您的 Activity
  4. 轮换设施

编辑

对于结果,

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (data != null) if (data.getParcelableExtra("data") != null)
Bitmap bitmap = data.getParcelableExtra("data");
}

再编辑

CropImage 文件中搜索 private void handleFace(FaceDetector.Face f) 方法。在 HighlightView hv = new HighlightView(mImageView); 这一行之后将以下代码放入方法中。

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

同时在 private void makeDefault() 方法中添加上述代码。

 private void makeDefault(){
HighlightView hv = new HighlightView(mImageView);

if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD) {
mImageView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
//rest of code
}

由于加速的某些原因,这是必要的。如果您在“GINGERBREAD”和“View.LAYOUT_TYPE_SOFTWARE”中遇到任何错误,请将您的 API 版本更改为 4.0 及更高版本。

确保你有像下面这样的 Activity 注册,

<activity
android:name="com.android.camera.CropImage"
android:hardwareAccelerated="false" />

注意

此示例应用程序的布局很脏。你需要自己说清楚。这是库项目,因此从项目属性中删除“is library”以运行该示例代码。

关于android - 图像的自定义裁剪无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17563765/

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