I'm developing Photoshop type app in which crop tools is using to crop image and i'm using default crop intent, when i cropped image i get bundle in which i got Rect(0,0-2,122) left,top,right,bottom but my point is when i cropped first time and again i cropped the cropper show its previously cropped area not default area and in crop intent.
CropIntent.putExtra("outputX", imageWidth);
CropIntent.putExtra("outputY", imageHeight);
CropIntent.putExtra("aspectX", 100);
CropIntent.putExtra("aspectY", -100);
CropIntent.putExtra("spotlightX", 10);
CropIntent.putExtra("spotlightY", -10);
I pass l,t,r,b like this, i know this is wrong but i tried aspect x and aspect y are ratios but spot light is what, i don't know. can i place cropper at previously cropped area on same image.
You can use this library from here
and use below method two recover the ratio on the image and call it where your image is to be cropped and remember when Activity is switched do not finish it.
public void updateCurrentCropViewOptions() {
CropImageViewOptions options = new CropImageViewOptions();
options.scaleType = mCropImageView.getScaleType();
options.cropShape = mCropImageView.getCropShape();
options.guidelines = mCropImageView.getGuidelines();
options.aspectRatio = mCropImageView.getAspectRatio();
options.fixAspectRatio = mCropImageView.isFixAspectRatio();
options.showCropOverlay = mCropImageView.isShowCropOverlay();
options.showProgressBar = mCropImageView.isShowProgressBar();
options.autoZoomEnabled = mCropImageView.isAutoZoomEnabled();
options.maxZoomLevel = mCropImageView.getMaxZoom();
options.flipHorizontally = mCropImageView.isFlippedHorizontally();
options.flipVertically = mCropImageView.isFlippedVertically();
}
Related
Am creating a document scanning application in android, am using OpenCV and Scan library in my project for cropping,I have created a rectangle using drawrect in camera view, now I need to capture the images inside that rectangle portion only and display it in another activity.
The image in question:
For me , I will take whole image, then crop.
Your question : "how do I know which part of the image is inside the rectangular portion, then only I can pass it nah, hope u understood". My answer is you can using relativity scaling of whole image dimension and camera display screen dimension. Then you will know which part of rectangular to be cropped.
This is the code example.
Note that you need to fill some codes to make it can save file into jpg, and save it after cropped.
// 1. Save your bitmap to file
public class MyPictureCallback implements Camera.PictureCallback {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
//mPictureFile is a file to save the captured image
FileOutputStream fos = new FileOutputStream(mPictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
}
}
}
// Somewhere in your code
// 2.1 Load bitmap from your .jpg file
Bitmap bitmap = BitmapFactory.decodeFile(path+"/mPictureFile_name.jpg");
// 2.2 Rotate the bitmap to be the same as display, if need.
... Add some bitmap rotate code
// 2.3 Size of rotated bitmap
int bitWidth = bitmap.getWidth();
int bitHeight = bitmap.getHeight();
// 3. Size of camera preview on screen
int preWidth = preview.getWidth();
int preHeight = preview.getHeight();
// 4. Scale it.
// Assume you draw Rect as "canvas.drawRect(60, 50, 210, 297, paint);" command
int startx = 60 * bitWidth / preWidth;
int starty = 50 * bitHeight / preHeight;
int endx = 210 * bitWidth / preWidth;
int endy = 297 * bitHeight / preHeight;
// 5. Crop image
Bitmap blueArea = Bitmap.createBitmap(bitmap, startx, starty, endx, endy);
// 6. Save Crop bitmap to file
This will work for you: How to programmatically take a screenshot in Android?
Make sure that the view (v1 in the code sample's case) passed in Bitmap.createBitmap(v1.getDrawingCache()) is a viewgroup that contains the image you want ot send to the second activity
Edit:
I don't think your intended flow is feasible. As far as I know, camera intents don't take arguments allowing to draw such a rectangle (I could be wrong though).
Instead, I suggest you take a picture, and then edit it with a library such as this one (https://github.com/ArthurHub/Android-Image-Cropper) or programatically as suggested above.
Here's what I need:
I have a Surface view that has a square (image view) on top of it. I need to capture an image, and crop out the area that was visible only within the square.
This code gives me decent results but specific only to some devices:
int width=(int)(bitmap.getWidth()*60/100);
int height=(bitmap.getHeight()*100/100); //dont change
bitmap=Bitmap.createBitmap(bitmap,150,0, width-55, height);
Is there any way I could generalize this code? Is there any other way to get what I need?
EDIT: This is how I got it to work-
Save the image from the surface view as a bitmap (This is very simple. There are many examples available on the internet that show how to do that)
Use this code in a function, and call it after the image is clicked
//bitmap is the object where the image is stored
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int left;
if(width > height){
left = (width - height)/2;
}
else {
left = (height - width)/2;
}
bitmap=Bitmap.createBitmap(bitmap,left,0, height, height);
I need to crop image, to square. I use that function:
private void crop(Uri imageUri) {
File photoGallery = new File(Environment.getExternalStorageDirectory(), "temp_image.jpg");
checkImageSize(photoGallery);
Intent cropIntentGallery = new Intent("com.android.camera.action.CROP");
cropIntentGallery.setDataAndType(imageUri, "image/*");
cropIntentGallery.putExtra("crop", true);
cropIntentGallery.putExtra("aspectX", 1);
cropIntentGallery.putExtra("aspectY", 1);
cropIntentGallery.putExtra("outputX", PHOTO_SIZE);
cropIntentGallery.putExtra("outputY", PHOTO_SIZE);
cropIntentGallery.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoGallery));
startActivityForResult(cropIntentGallery, REQ_EDIT_CAMERA);
}
And it opens crop activity, but I can change X and Y size.
What I need is to fix smallest dimension, so if image was made in landscape mode - user will be able to cut left or/and right edges, if in portrait - top or/and bottom edges.
Is there are some extra parameter to do this?
BTW, where I can find list of all possible intent extras? (like: "aspectX", "outputX"...)
I have a code in which I call the gallery to select an image that i show in a imageview . This works fine and maintains the aspect ratio.
The problem is when the image size is larger than 2048 x 2048
I am using this code when it is the case:
uriIsNowAbitmap =
MediaStore.Images.Media.getBitmap(this.getContentResolver(),
selectedImageUri);
//...
int height = uriIsNowAbitmap.getHeight();
int width = uriIsNowAbitmap.getWidth();
if ((width>=2048)||(height>=2048)) {
int newheight = height/10; // height in pixels
int newwidth = width/10; // width in pixels
Bitmap avatarScaled = Bitmap.createScaledBitmap(uriIsNowAbitmap, newwidth, newheight, true);
previewNewAvatar.setImageBitmap(avatarScaled);
}
also works correctly, but with a problem. The images are not of the type shown rotated landscape
to try to explain, I put this example. This is the picture of the gallery:
when I select the picture and assign it to the imageview is shown rotated:
I do not understand why. I've tried a thousand ways and have read a lot of information about resize, i have read threads and sample code for this website (Android: high quality image resizing / scaling) and and many more... but nothing helps.
The intention is to show in this way ...make it with photoshop :)
I appreciate any help, took many hours trying to fix it
Regards
Firstly, you will have to detect the orientation change, and when you detect a change to landscape orientation you just rotate your bitmap accordingly. You will have to declare your Bitmap avatarScaled as a global variable in order to access it in the onConfigurationChanged() method below:
Use the onConfigurationChanged method of Activity to detect change in orientation. See the following code:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotated = Bitmap.createBitmap(avatarScaled, 0, 0, avatarScaled.getWidth(),
avatarScaled.getHeight(), matrix, true);
previewNewAvatar.setImageBitmap(rotated);
}
}
You also have to edit the appropriate element in your manifest file to include the android:configChanges Just see the code below:
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
I'm writing an app that uses the phone's camera to take a picture, and then display it. The problem is, for phones that have high-res cameras, this caused the app to crash, so I lowered the resolution using isSampleSize, which solved this issue. But now I have a problem with phones that have lower resolution cameras - the picture has terrible quality. Is there any way to check what the image memory consumption is, and according to that decide whether I want to lower the quality or not?
To rescale my picture, because I had a limitaion in the image height, I used the code below to resize it. But i didnt wan't to resize the bmp unless it was above my height requirement, hope you can use it. (Used a stream to get my pictures in)
if (stream != null) {
img = BitmapFactory.decodeStream(stream, null, o);
float imgHeight = (float) img.getHeight();
Display display = ((WindowManager) ctx.getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay();
float displayHeight = (float) (display.getHeight()-50);
if(imgHeight>displayHeight) {
float scaleFactor = displayHeight/imgHeight;
img = Bitmap.createScaledBitmap(img, (int)(img.getWidth()*scaleFactor), (int)(imgHeight*scaleFactor), false);
}
saveBitmap(new File(getSdPath() + location), img);
}