在我的应用中,我尝试从所选用户形状中裁剪位图。 我已经阅读了很多关于这个问题的内容,但我仍然无法找到任何解决方案。 裁剪后得到的图像不是我标记的图像。
这是我的代码:
public class TestView extends ImageView implements OnTouchListener {
private Paint paint;
public static List<Point> points;
Bitmap bitmapMain;
Context mContext;
private int leftX = 0;
private int rightX = 0;
private int upY = 0;
private int downY = 0;
public TestView(Context c) {
super(c);
mContext = c;
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(new DashPathEffect(new float[] { 10, 20 }, 0));
paint.setStrokeWidth(5);
paint.setColor(Color.WHITE);
this.setOnTouchListener(this);
points = new ArrayList<Point>();
}
public TestView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
this.setOnTouchListener(this);
points = new ArrayList<Point>();
}
public void setBitmap(Bitmap bit)
{
bitmapMain = bit;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
// canvas.drawBitmap(bitmap, 0, 0, null);
Path path = new Path();
boolean first = true;
for (int i = 0; i < points.size(); i += 2) {
Point point = points.get(i);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else if (i < points.size() - 1) {
Point next = points.get(i + 1);
path.quadTo(point.x, point.y, next.x, next.y);
} else {
path.lineTo(point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_OUTSIDE || event.getAction() == MotionEvent.ACTION_CANCEL)
{
return true;
}
int intX = (int) (event.getX());
int intY = (int) (event.getY());
if(event.getAction() == MotionEvent.ACTION_DOWN)
{
leftX = intX;
rightX = intX;
downY = intY;
upY = intY;
}
Point point = new Point();
point.x = intX;
point.y = intY;
if(intX < leftX)
leftX = intX;
if(intX > rightX)
rightX = intX;
if(intY > downY)
downY = intY;
if(intY < upY)
upY = intY;
points.add(point);
invalidate();
return true;
}
public void clear()
{
leftX = 0;
rightX = 0;
upY = 0;
downY = 0;
points.clear();
paint.setColor(Color.WHITE);
paint.setStyle(Style.STROKE);
invalidate();
}
public Bitmap getImage2()
{
//getting the size of the new bitmap
int newHeight = rightX - leftX;
int newWidth = downY - upY;
Bitmap resultingImage = Bitmap.createBitmap(newHeight, newWidth, Config.ARGB_8888);
Canvas canvas = new Canvas(resultingImage);
Paint paint = new Paint();
paint.setAntiAlias(true);
Path path = new Path();
for (int i = 0; i < points.size() - 1; i++) {
path.quadTo((float)points.get(i).x, (float)points.get(i).y, (float)points.get(i+1).x, (float)points.get(i+1).y);
// path.lineTo(points.get(i).x, points.get(i).y);
}
//closing the shape, connection last point to the first one
path.quadTo((float)points.get(points.size()-1).x, (float)points.get(points.size()-1).y, (float)points.get(0).x, (float)points.get(0).y);
//drawing user shape
canvas.drawPath(path, paint);
//getting image inside the shape
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawBitmap(bitmapMain, 0, 0, paint);
return resultingImage;
}
}
我的活动:
public class MainActivity extends Activity implements OnClickListener {
private TestView drawing;
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final String IMAGE_DIRECTORY_NAME = "demo pictures";
private Uri fileUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//drawing = (SignatureViewModed) findViewById(R.id.myTest);
findViewById(R.id.button1).setOnClickListener(this);
findViewById(R.id.button2).setOnClickListener(this);
findViewById(R.id.button3).setOnClickListener(this);
drawing = (TestView) findViewById(R.id.images);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId())
{
case R.id.button1:
{
drawing.clear();
break;
}
case R.id.button2:
{
if(isDeviceSupportCamera())
captureImage();
else
Toast.makeText(this, "No camera", Toast.LENGTH_SHORT).show();
break;
}
case R.id.button3:
{
showCutImage();
break;
}
}
}
private boolean isDeviceSupportCamera() {
if (getApplicationContext().getPackageManager().hasSystemFeature(
PackageManager.FEATURE_CAMERA)) {
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
private void captureImage() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri();
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
public Uri getOutputMediaFileUri() {
return Uri.fromFile(getOutputMediaFile());
}
/**
* returning image / video
*/
private static File getOutputMediaFile() {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
return mediaFile;
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// save file url in bundle as it will be null on scren orientation
// changes
outState.putParcelable("file_uri", fileUri);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// get the file url
fileUri = savedInstanceState.getParcelable("file_uri");
}
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data2) {
Bitmap bitmap = null;
if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
if (resultCode == RESULT_OK)
{
String filePath = fileUri.getPath();
bitmap = decodeSampledBitmapFromPath(filePath, true);
drawing.setBitmap(bitmap);
drawing.setImageBitmap(bitmap);
}
}
super.onActivityResult(requestCode, resultCode, data2);
}
public Bitmap decodeSampledBitmapFromPath(String path, boolean isFullScreen) {
Bitmap bmp = null;
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
if(isFullScreen)
options.inSampleSize = calculateInSampleSize(options, getScreenWidth() , getScreenHeight());
else
options.inSampleSize = calculateInSampleSize(options, 200, 200);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
bmp = BitmapFactory.decodeFile(path, options);
return bmp;
}
public int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
@SuppressLint("NewApi")
public int getScreenHeight()
{
Display display = ((WindowManager) this.getSystemService(WINDOW_SERVICE))
.getDefaultDisplay();
int height = 0;
if (android.os.Build.VERSION.SDK_INT >= 13) {
Point size = new Point();
display.getSize(size);
height = size.y;
} else {
height = display.getHeight();
}
return height;
}
@SuppressLint("NewApi")
public int getScreenWidth()
{
Display display = ((WindowManager) this.getSystemService(WINDOW_SERVICE))
.getDefaultDisplay();
int width = 0;
if (android.os.Build.VERSION.SDK_INT >= 13) {
Point size = new Point();
display.getSize(size);
width = size.x;
} else {
width = display.getWidth();
}
return width;
}
public void showCutImage()
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
View prefView = View.inflate(this,R.layout.image_show, null);
ImageView image = (ImageView) prefView.findViewById(R.id.imageView1);
image.setImageBitmap(drawing.getImage2());
builder.setView(prefView);
builder.show();
}
这是我的结果的2张照片。 你可以看到我得到的图片不是我标记的整个区域,而是它有额外的角落。
答案 0 :(得分:1)
你应该关闭路径。 将testView的onDraw方法更改为
public void onDraw(Canvas canvas){ super.onDraw(帆布);
// canvas.drawBitmap(bitmap, 0, 0, null); Path path = new Path(); boolean first = true; for (int i = 0; i < points.size(); i += 2) { Point point = points.get(i); if (first) { first = false; path.moveTo(point.x, point.y); } else if (i < points.size() - 1) { Point next = points.get(i + 1); path.quadTo(point.x, point.y, next.x, next.y); } else { path.lineTo(point.x, point.y); } } path.lineTo(points.get(0).x,points.get(0).y); canvas.drawPath(path, paint); }