#android
#Android
Вопрос:
Я пытаюсь создать приложение, в которое мне нужно добавить функцию обрезки от руки. Я использовал https://github.com/TomiGie/Android-FreeHandCropView этот проект, чтобы интегрировать его в мой проект.
Проблема в том, что когда я пытаюсь добавить изображение, снятое с камеры, оно кажется очень большим на экране, и я не могу обрезать полное изображение. Вот код, который я пробовал.
Это CropVIEW, в котором есть код обрезки.
package com.idoideas.stickermaker.WhatsAppBasedCode;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
import java.util.List;
public class CropView extends View implements View.OnTouchListener {
private Paint paint;
private List<Point> points;
boolean flgPathDraw = true;
Point mfirstpoint = null;
boolean bfirstpoint;
Point mlastpoint = null;
Bitmap bitmap;
Context mContext;
public CropView(Context c, Bitmap bitmap) {
super(c);
mContext = c;
this.bitmap = bitmap;
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.RED);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
this.setOnTouchListener(this);
points = new ArrayList<>();
bfirstpoint = false;
}
public CropView(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(5);
paint.setColor(Color.RED);
points = new ArrayList<>();
bfirstpoint = false;
this.setOnTouchListener(this);
}
public void onDraw(Canvas canvas) {
/*Rect dest = new Rect(0, 0, getWidth(), getHeight());
paint.setFilterBitmap(true); canvas.drawBitmap(bitmap, null, dest, paint);*/
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 {
mlastpoint = points.get(i);
path.lineTo(point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
// if(event.getAction() != MotionEvent.ACTION_DOWN)
// return super.onTouchEvent(event);
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
if (flgPathDraw) {
if (bfirstpoint) {
if (comparepoint(mfirstpoint, point)) {
// points.add(point);
points.add(mfirstpoint);
flgPathDraw = false;
showcropdialog();
} else {
points.add(point);
}
} else {
points.add(point);
}
if (!(bfirstpoint)) {
mfirstpoint = point;
bfirstpoint = true;
}
}
invalidate();
Log.e("Hi ==>", "Size: " point.x " " point.y);
if (event.getAction() == MotionEvent.ACTION_UP) {
Log.d("Action up*****~~>>>>", "called");
mlastpoint = point;
if (flgPathDraw) {
if (points.size() > 12) {
if (!comparepoint(mfirstpoint, mlastpoint)) {
flgPathDraw = false;
points.add(mfirstpoint);
showcropdialog();
}
}
}
}
return true;
}
private boolean comparepoint(Point first, Point current) {
int left_range_x = current.x - 3;
int left_range_y = current.y - 3;
int right_range_x = current.x 3;
int right_range_y = current.y 3;
if ((left_range_x < first.x amp;amp; first.x < right_range_x)
amp;amp; (left_range_y < first.y amp;amp; first.y < right_range_y)) {
return points.size() >= 10;
} else {
return false;
}
}
public void fillinPartofPath() {
Point point = new Point();
point.x = points.get(0).x;
point.y = points.get(0).y;
points.add(point);
invalidate();
}
public void resetView() {
points.clear();
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
points = new ArrayList<>();
bfirstpoint = false;
flgPathDraw = true;
invalidate();
}
private void showcropdialog() {
DialogInterface.OnClickListener dialogClickListener = (dialog, which) -> {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
((MainActivity) mContext).cropImage();
break;
case DialogInterface.BUTTON_NEGATIVE:
/*// No button clicked
intent = new Intent(mContext, DisplayCropActivity.class);
intent.putExtra("crop", false); mContext.startActivity(intent);
bfirstpoint = false;*/
resetView();
break;
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage("Do you Want to save Crop or Non-crop image?")
.setPositiveButton("Crop", dialogClickListener)
.setNegativeButton("Non-crop", dialogClickListener).show()
.setCancelable(false);
}
public List<Point> getPoints() {
return points;
}
}
и это мой MainActivity, в котором я добавляю этот CropVIEW для обрезки.
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Region;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.idoideas.stickermaker.R;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
private Bitmap mBitmap;
private CropView mSomeView;
private Button continueBtn;
private static final int CROPPED_MARGIN = 100;
private Uri uri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Objects.requireNonNull(getSupportActionBar()).setTitle("Crop Image");
mBitmap = DataHolder.getInstance().getBitmap();
mSomeView = new CropView(this, mBitmap);
continueBtn = findViewById(R.id.continueBtn);
LinearLayout layout = findViewById(R.id.layout);
LinearLayout.LayoutParams lp =
new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
layout.addView(mSomeView, lp);
continueBtn.setOnClickListener(v -> withoutCropImage());
}
private void withoutCropImage() {
Uri uri = getImageUri(mBitmap, Bitmap.CompressFormat.PNG, 100);
Intent intent = new Intent();
intent.putExtra("uri", uri.toString());
setResult(2, intent);
finish();
}
public void cropImage() {
setContentView(R.layout.activity_picture_preview);
ImageView imageView = findViewById(R.id.image);
Button cancel_action = findViewById(R.id.cancel_action);
Button save_action = findViewById(R.id.save_action);
Bitmap fullScreenBitmap =
Bitmap.createBitmap(mSomeView.getWidth(), mSomeView.getHeight(), mBitmap.getConfig());
Canvas canvas = new Canvas(fullScreenBitmap);
canvas.drawColor(Color.TRANSPARENT);
Path path = new Path();
List<Point> points = mSomeView.getPoints();
for (int i = 0; i < points.size(); i ) {
path.lineTo(points.get(i).x, points.get(i).y);
}
// Cut out the selected portion of the image...
Paint paint = new Paint();
canvas.drawPath(path, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(mBitmap, 0, 0, paint);
// Frame the cut out portion...
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10f);
canvas.drawPath(path, paint);
// Create a bitmap with just the cropped area.
Region region = new Region();
Region clip = new Region(0, 0, fullScreenBitmap.getWidth(), fullScreenBitmap.getHeight());
region.setPath(path, clip);
Rect sourceBounds = region.getBounds();
Rect destBounds =
new Rect(CROPPED_MARGIN, CROPPED_MARGIN, sourceBounds.width() CROPPED_MARGIN,
sourceBounds.height() CROPPED_MARGIN);
Bitmap croppedBitmap =
Bitmap.createBitmap(sourceBounds.width() CROPPED_MARGIN * 2,
sourceBounds.height() CROPPED_MARGIN * 2, mBitmap.getConfig());
canvas.setBitmap(croppedBitmap);
canvas.drawBitmap(fullScreenBitmap, sourceBounds, destBounds, null);
if (croppedBitmap != null) {
uri = getImageUri(croppedBitmap, Bitmap.CompressFormat.PNG, 90);
}
imageView.setImageBitmap(croppedBitmap);
cancel_action.setOnClickListener(v -> {
DataHolder.getInstance().clearDataHolder();
finish();
});
save_action.setOnClickListener(v -> {
if (uri != null amp;amp; !TextUtils.isEmpty(uri.toString())) {
Intent intent = new Intent();
intent.putExtra("uri", uri.toString());
setResult(2, intent);
finish();
} else {
Toast.makeText(this, "Something went wrong...", Toast.LENGTH_SHORT).show();
Intent intent = new Intent();
intent.putExtra("uri", "");
setResult(2, intent);
finish();
}
});
}
public Uri getImageUri(Bitmap src, Bitmap.CompressFormat format, int quality) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
src.compress(format, quality, os);
String dateCreated = SimpleDateFormat.getDateInstance().format(new Date());
String path = MediaStore.Images.Media.insertImage(getContentResolver(), src, dateCreated, null);
return Uri.parse(path);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
@Override
public void onBackPressed() {
DataHolder.getInstance().clearDataHolder();
finish();
super.onBackPressed();
}
}
Пожалуйста, помогите мне, если кто-нибудь знает решение. Заранее спасибо.
Комментарии:
1. Растровое изображение отрисовано в естественном масштабе, поэтому вы видите только его часть. На самом деле ваши прокомментированные части изменили бы его размер по размеру, но вам нужно было бы изменить масштаб результирующих точек.
2. какая прокомментированная часть?