Reputation: 106
I need a bit of help. I have an ImageView with a touch listener, and I am able to capture all touch inputs into a matrix, and apply that matrix to the ImageView and VOILA! the image pans and zooms appropriately.
Here is the trouble: I'd now like to CROP the image in such a way that it ALWAYS ends up the same size; eg a 300x300 image.
In other words, suppose I have a 300x300 square in the middle of my screen, a user pans and zooms an image until an item of interest fits into that square, and hits "next". I would like to have a resulting image that has cropped the photo to only be the 300x300 portion that was contained in the box.
Make sense?? Please help! Thanks comrades! See a bit of code below for what I have tried thus far.
float[] matrixVals = new float[9];
ImageTouchListener.persistedMatrix.getValues(matrixVals);
model.setCurrentBitmap(Bitmap.createBitmap(model.getOriginalBitmap(), 0, 0, model.getTargetWidth(), model.getTargetHeight(), ImageTouchListener.persistedMatrix, true));
model.setCurrentBitmap(Bitmap.createBitmap(model.getCurrentBitmap(), Math.round(matrixVals[Matrix.MTRANS_X]), Math.round(matrixVals[Matrix.MTRANS_Y]), model.getTargetWidth(), model.getTargetHeight(), null, false));
Finally, I would also like to be able to SHRINK the image into the box, where the edges may actually need to be filled in with black or white or some kind of border... So far, everything I do other than no pan or zoom at all crashes when I hit next.
Thanks again!
Upvotes: 0
Views: 1089
Reputation: 24720
see this custom ImageView, the most important part is onTouchEvent where cropped Bitmap is created and saved to /sdcard for verification:
class IV extends ImageView {
Paint paint = new Paint();
Rect crop = new Rect();
public IV(Context context) {
super(context);
paint.setColor(0x660000ff);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
crop.set(w / 2, h / 2, w / 2, h / 2);
crop.inset(-75, -75);
}
@Override
public void setImageResource(int resId) {
super.setImageResource(resId);
setScaleType(ScaleType.MATRIX);
Matrix m = getImageMatrix();
m.postScale(2, 2);
m.postTranslate(40, 30);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
Bitmap croppedBitmap = Bitmap.createBitmap(crop.width(), crop.height(), Config.ARGB_8888);
Canvas c = new Canvas(croppedBitmap);
c.translate(-crop.left, -crop.top);
c.concat(getImageMatrix());
getDrawable().draw(c);
// just save it for test verification
try {
OutputStream stream = new FileOutputStream("/sdcard/test.png");
croppedBitmap.compress(CompressFormat.PNG, 100, stream);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return false;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawRect(crop, paint);
}
}
Upvotes: 1
Reputation: 3263
It's not really clear for me what your problem is, a calculation or a drawing problem ... if it is a drawing problem I might have the solution ...
Create a new bitmap, get the canvas and draw the correct rect of the big image into the new smaller one ....
Bitmap bigPicture; //your big picture
Bitmap bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
Rect source = ...
Rect dest = ...
c.drawBitmap(bigPicture, source, dest, paint);
Now if your problem is a calculation problem I might have a solution too ...
Upvotes: 0