作物与位图对象的路径 [英] Crop bitmap with Path object
问题描述
在我的应用我试着从裁剪选定的用户形状位图。
我读了很多关于这个问题,我仍然不能找到任何解决方案。
裁剪后,我得到的图像是不是我有显着的形象。
下面是我的code:
公共类TestView扩展了ImageView的实现OnTouchListener {
私人涂料粉刷;
公共静态列表<点和GT;点; 位图bitmapMain; 上下文mContext; 私人INT leftX = 0;
私人INT rightX = 0;
私人INT upY = 0;
私人INT柔和= 0; 公共TestView(上下文C){
超(C); mContext = C;
setFocusable(真);
setFocusableInTouchMode(真); 油漆=新的油漆(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setPathEffect(新DashPathEffect(新浮法[] {10,20},0));
paint.setStrokeWidth(5);
paint.setColor(Color.WHITE); this.setOnTouchListener(本);
点=新的ArrayList<点和GT;();
} 公共TestView(上下文的背景下,ATTRS的AttributeSet){
超(背景下,ATTRS);
mContext =背景;
setFocusable(真);
setFocusableInTouchMode(真); 油漆=新的油漆(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE); this.setOnTouchListener(本);
点=新的ArrayList<点和GT;(); } 公共无效setBitmap(位图位)
{
bitmapMain =位;
} 公共无效的onDraw(帆布油画){
super.onDraw(画布); // canvas.drawBitmap(位图,0,0,NULL); 路径path =新路径();
布尔第一= TRUE; 的for(int i = 0; I< points.size(); I + = 2){
逐点= points.get(I)
如果(第一){
第一= FALSE;
path.moveTo(point.x,point.y);
}否则如果(I所述; points.size() - 1){
点下= points.get第(i + 1);
path.quadTo(point.x,point.y,next.x,next.y);
}其他{
path.lineTo(point.x,point.y);
}
}
canvas.drawPath(路径,油漆);
} 公共布尔onTouch(查看视图,MotionEvent事件){
如果(event.getAction()== MotionEvent.ACTION_UP || event.getAction()== MotionEvent.ACTION_OUTSIDE || event.getAction()== MotionEvent.ACTION_CANCEL)
{
返回true;
} INT INTX =(int)的(event.getX());
INT intY的=(int)的(event.getY()); 如果(event.getAction()== MotionEvent.ACTION_DOWN)
{
leftX = INTX;
rightX = INTX;
柔和intY的=;
upY intY的=;
} 逐点=新点(); point.x = INTX;
point.y intY的=; 如果(INTX< leftX)
leftX = INTX;
如果(INTX> rightX)
rightX = INTX;
如果(与intY的GT;霜霉病)
柔和intY的=;
如果(与intY的LT; upY)
upY intY的=; points.add(点);
无效(); 返回true;
} 公共无效清除()
{
leftX = 0;
rightX = 0;
upY = 0;
柔和= 0; points.clear();
paint.setColor(Color.WHITE);
paint.setStyle(Style.STROKE);
无效();
}
公共位图getImage2()
{ //获得新位图的大小 INT newHeight = rightX - leftX;
INT newWidth =柔和 - upY; 位图resultingImage = Bitmap.createBitmap(newHeight,newWidth,Config.ARGB_8888); 帆布帆布=新的Canvas(resultingImage);
涂料粉刷=新的油漆();
paint.setAntiAlias(真); 路径path =新路径();
的for(int i = 0; I< points.size() - 1;我++){ path.quadTo((浮点)points.get(I).X,(浮点)points.get(I).Y,(浮点)points.get第(i + 1).X,(浮点)points.get(我+1).Y);
// path.lineTo(points.get(我).X,points.get(我).Y);
}//闭合形状,连接最后一点与第一个 path.quadTo((浮点)points.get(points.size() - 1).X,(浮点)points.get(points.size() - 1).Y,(浮点)points.get(0)。 X,(浮点)points.get(0).Y); //绘制形状用户 canvas.drawPath(路径,油漆); //获取形状内部图像 paint.setXfermode(新PorterDuffXfermode(Mode.DST_IN)); canvas.drawBitmap(bitmapMain,0,0,油漆); 返回resultingImage;
} }
我的活动:
公共类MainActivity扩展活动实现OnClickListener { 私人TestView图;
私有静态最终诠释CAMERA_CAPTURE_IMAGE_REQUEST_ code = 100;
公共静态最终诠释MEDIA_TYPE_IMAGE = 1;
私有静态最后弦乐IMAGE_DIRECTORY_NAME =试玩画面;
私人乌里了fileURI;
@覆盖
保护无效的onCreate(捆绑savedInstanceState){ this.requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_main); //绘制=(SignatureViewModed)findViewById(R.id.myTest);
findViewById(R.id.button1).setOnClickListener(本);
findViewById(R.id.button2).setOnClickListener(本);
findViewById(R.id.button3).setOnClickListener(本); 绘制=(TestView)findViewById(R.id.images); } @覆盖
公共布尔onCreateOptionsMenu(菜单菜单){
//充气菜单;如果是present这增加了项目操作栏。
。getMenuInflater()膨胀(R.menu.main,菜单);
返回true;
} @覆盖
公共无效的onClick(查看为arg0){
// TODO自动生成方法存根 开关(arg0.getId())
{ 案例R.id.button1:
{
drawing.clear();
打破;
} 案例R.id.button2:
{
如果(isDeviceSupportCamera())
captureImage();
其他
Toast.makeText(这一点,无摄像头,Toast.LENGTH_SHORT).show();
打破;
} 案例R.id.button3:
{
showCutImage();
打破;
} } } 私人布尔isDeviceSupportCamera(){
如果(getApplicationContext()。getPackageManager()。hasSystemFeature(
PackageManager.FEATURE_CAMERA)){
//这个设备有一个摄像头
返回true;
}其他{
//此设备上没有摄像头
返回false;
}
} 私人无效captureImage(){ 意向意图=新意图(MediaStore.ACTION_IMAGE_CAPTURE); 了fileURI = getOutputMediaFileUri(); intent.putExtra(MediaStore.EXTRA_OUTPUT,fileURI所); //启动图像拍摄意图
startActivityForResult(意向,CAMERA_CAPTURE_IMAGE_REQUEST_ code);
} 公共乌里getOutputMediaFileUri(){
返回Uri.fromFile(getOutputMediaFile());
} / **
*返回图像/视频
* /
私有静态文件getOutputMediaFile(){ //外接SD卡的位置
文件mediaStorageDir =新的文件(
环境
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
IMAGE_DIRECTORY_NAME); //创建存储目录,如果它不存在
如果(!mediaStorageDir.exists()){
如果(!mediaStorageDir.mkdirs()){
Log.d(IMAGE_DIRECTORY_NAME,哎呀!失败创造
+ IMAGE_DIRECTORY_NAME +目录);
返回null;
}
} //创建一个媒体文件名
字符串的timeStamp =新的SimpleDateFormat(YYYYMMDD_HHMMSS
。Locale.getDefault())格式(新的Date());
文件媒体文件; 媒体文件=新的文件(mediaStorageDir.getPath()+文件分割符+IMG_+ +的timeStamp.JPG); 返回媒体文件;
} @覆盖
保护无效的onSaveInstanceState(捆绑outState){
super.onSaveInstanceState(outState); //保存文件的URL捆绑,因为它会在scren方向空
//改变
outState.putParcelable(file_uri了fileURI);
} @覆盖
保护无效onRestoreInstanceState(捆绑savedInstanceState){
super.onRestoreInstanceState(savedInstanceState); //获取文件的URL
了fileURI = savedInstanceState.getParcelable(file_uri);
}
@覆盖
保护无效的onActivityResult(INT申请code,INT结果code,
意向数据2){ 位图位图= NULL; 如果(要求code == CAMERA_CAPTURE_IMAGE_REQUEST_ code){ 如果(结果code == RESULT_OK)
{ 串文件路径= fileUri.getPath();
位=去codeSampledBitmapFromPath(文件路径,真实); drawing.setBitmap(位图); drawing.setImageBitmap(位图);
} } super.onActivityResult(要求code,结果code,数据2);
} 公共位图德codeSampledBitmapFromPath(字符串路径,布尔isFullScreen){ BMP位图= NULL;
最后BitmapFactory.Options选项=新BitmapFactory.Options();
options.inJustDe codeBounds = TRUE; BitmapFactory.de codeFILE(路径选择); 如果(isFullScreen)
options.inSampleSize = calculateInSampleSize(选项,getScreenWidth(),getScreenHeight());
其他
options.inSampleSize = calculateInSampleSize(选项,200,200); //德code位与inSampleSize集
options.inJustDe codeBounds = FALSE;
BMP = BitmapFactory.de codeFILE(路径选择); 返回BMP;
} 公众诠释calculateInSampleSize(BitmapFactory.Options选项,
INT reqWidth,诠释reqHeight){ 最终诠释身高= options.outHeight;
最终诠释宽度= options.outWidth;
INT inSampleSize = 1; 如果(高度> reqHeight ||宽度GT; reqWidth){
如果(宽>高度){
inSampleSize = Math.round((浮点)高度/(浮点)reqHeight);
}其他{
inSampleSize = Math.round((浮点)宽/(浮点)reqWidth);
}
}
返回inSampleSize;
} @燮pressLint(NewApi)
公众诠释getScreenHeight()
{
显示显示=((窗口管理器)this.getSystemService(WINDOW_SERVICE))
.getDefaultDisplay(); INT高度= 0; 如果(android.os.Build.VERSION.SDK_INT> = 13){
点大小=新点();
display.getSize(大小);
高度= size.y; }其他{
高度= display.getHeight(); } 返回高度;
} @燮pressLint(NewApi)
公众诠释getScreenWidth()
{
显示显示=((窗口管理器)this.getSystemService(WINDOW_SERVICE))
.getDefaultDisplay(); INT宽度= 0; 如果(android.os.Build.VERSION.SDK_INT> = 13){
点大小=新点();
display.getSize(大小); 宽度= size.x;
}其他{ 宽度= display.getWidth();
} 返回宽度;
} 公共无效showCutImage()
{
AlertDialog.Builder建设者=新AlertDialog.Builder(本); 查看prefView = View.inflate(这一点,R.layout.image_show,NULL); ImageView的图像=(ImageView的)prefView.findViewById(R.id.imageView1); image.setImageBitmap(drawing.getImage2()); builder.setView(prefView); builder.show(); }
下面是我的结果的2张图片。
你可以看到我得到的图片是不是整个区域标志着我和它得到了额外的角落。
您应该关闭的路径。
更改testView的方法来的onDraw
公共无效的onDraw(帆布油画){
super.onDraw(画布);// canvas.drawBitmap(位图,0,0,NULL); 路径path =新路径();
布尔第一= TRUE; 的for(int i = 0; I< points.size(); I + = 2){
逐点= points.get(I)
如果(第一){
第一= FALSE;
path.moveTo(point.x,point.y);
}否则如果(I所述; points.size() - 1){
点下= points.get第(i + 1);
path.quadTo(point.x,point.y,next.x,next.y);
}其他{
path.lineTo(point.x,point.y);
}
}
path.lineTo(points.get(0).X,points.get(0).Y);
canvas.drawPath(路径,油漆);
}
块引用>In my app I try to crop bitmap from selected user shape. I have read a lot about this issue and still I cant find any solution. The image I get after the cropping is not the image that I have marked.
Here is my code:
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; } }
My activity:
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(); }
Here is 2 pictures of my results. You can see the the picture I got is not the whole area I marked and its got extra corner.
解决方案You should close the path. Change the method onDraw of testView to
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); } } path.lineTo(points.get(0).x,points.get(0).y); canvas.drawPath(path, paint); }
这篇关于作物与位图对象的路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!