Skip to content
This repository has been archived by the owner on Jan 7, 2023. It is now read-only.

Fix Rotation Errors, withJpgQuality() added, Photo Action, Clean code (Min SDK 19) #190

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ archivesBaseName = 'android-crop-example'

android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
buildToolsVersion '23.0.2'

defaultConfig {
minSdkVersion 10
targetSdkVersion 22
minSdkVersion 19
targetSdkVersion 23
versionCode Integer.parseInt(project.VERSION_CODE)
versionName project.VERSION
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,27 +1,34 @@
package com.soundcloud.android.crop.example;

import com.soundcloud.android.crop.Crop;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;

import com.soundcloud.android.crop.Crop;

import java.io.File;

public class MainActivity extends Activity {

private ImageView resultView;
private int REQUEST_PHOTO = 1;
private File PHOTO_CAPTURED, PHOTO_CROPPED;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
resultView = (ImageView) findViewById(R.id.result_image);

PHOTO_CAPTURED = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "PhotoCaptured.jpg");
PHOTO_CROPPED = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "PhotoCropped.jpg");
}

@Override
Expand All @@ -36,22 +43,36 @@ public boolean onOptionsItemSelected(MenuItem item) {
resultView.setImageDrawable(null);
Crop.pickImage(this);
return true;
} else if (item.getItemId() == R.id.action_camera) {
resultView.setImageDrawable(null);
takePhoto();
return true;
}
return super.onOptionsItemSelected(item);
}

private void takePhoto() {
final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(PHOTO_CAPTURED));
startActivityForResult(intent, REQUEST_PHOTO);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result) {
if (requestCode == Crop.REQUEST_PICK && resultCode == RESULT_OK) {
beginCrop(result.getData());
} else if (requestCode == REQUEST_PHOTO && resultCode == RESULT_OK) {
beginCrop(Uri.fromFile(PHOTO_CAPTURED));
} else if (requestCode == Crop.REQUEST_CROP) {
handleCrop(resultCode, result);
}
}

private void beginCrop(Uri source) {
Uri destination = Uri.fromFile(new File(getCacheDir(), "cropped"));
Crop.of(source, destination).asSquare().start(this);
Crop.of(source, Uri.fromFile(PHOTO_CROPPED))
.withMaxSize(1600,1600)
.withJpgQuality(90)
.start(this);
}

private void handleCrop(int resultCode, Intent result) {
Expand All @@ -61,5 +82,4 @@ private void handleCrop(int resultCode, Intent result) {
Toast.makeText(this, Crop.getError(result).getMessage(), Toast.LENGTH_SHORT).show();
}
}

}
3 changes: 3 additions & 0 deletions example/src/main/res/menu/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
android:title="@string/action_select"
android:showAsAction="always" />

<item android:id="@+id/action_camera"
android:title="Photo"
android:showAsAction="always" />
</menu>
6 changes: 3 additions & 3 deletions lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ archivesBaseName = 'android-crop'

android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
buildToolsVersion '23.0.2'

defaultConfig {
minSdkVersion 10
targetSdkVersion 22
minSdkVersion 19
targetSdkVersion 23

testApplicationId 'com.soundcloud.android.crop.test'
testInstrumentationRunner 'android.test.InstrumentationTestRunner'
Expand Down
13 changes: 13 additions & 0 deletions lib/src/main/java/com/soundcloud/android/crop/Crop.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ interface Extra {
String ASPECT_Y = "aspect_y";
String MAX_X = "max_x";
String MAX_Y = "max_y";
String JPG_QUALITY = "jpg_quality";
String ERROR = "error";
}

Expand Down Expand Up @@ -79,6 +80,18 @@ public Crop withMaxSize(int width, int height) {
return this;
}

/**
* Set JPG quality
*
* @param quality JPG Quality (10< q <100)
*/
public Crop withJpgQuality(int quality) {
if ( (quality>=10) || (quality<=100) ) {
cropIntent.putExtra(Extra.JPG_QUALITY, quality);
}
return this;
}

/**
* Send the crop Intent from an Activity
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,23 +295,22 @@ private void onSaveClicked() {
}

if (croppedImage != null) {
imageView.setImageRotateBitmapResetBase(new RotateBitmap(croppedImage, exifRotation), true);
imageView.center();
//imageView.setImageRotateBitmapResetBase(new RotateBitmap(croppedImage, exifRotation), true);
//imageView.center();
imageView.highlightViews.clear();
}
saveImage(croppedImage);
}

private void saveImage(Bitmap croppedImage) {
if (croppedImage != null) {
final Bitmap b = croppedImage;
private void saveImage(final Bitmap b) {
if (b != null) {
CropUtil.startBackgroundJob(this, null, getResources().getString(R.string.crop__saving),
new Runnable() {
public void run() {
saveOutput(b);
b.recycle();
}
}, handler
);
}, handler);
} else {
finish();
}
Expand All @@ -337,18 +336,29 @@ private Bitmap decodeRegionCrop(Rect rect, int outWidth, int outHeight) {
RectF adjusted = new RectF();
matrix.mapRect(adjusted, new RectF(rect));

//if the cutting box are rectangle( outWidth != outHeight ),and the exifRotation is 90 or 270,
//the outWidth and outHeight should be interchanged
if (exifRotation==90 || exifRotation==270) {
int temp=outWidth;
outWidth=outHeight;
outHeight=temp;
}

// Adjust to account for origin at 0,0
adjusted.offset(adjusted.left < 0 ? width : 0, adjusted.top < 0 ? height : 0);
rect = new Rect((int) adjusted.left, (int) adjusted.top, (int) adjusted.right, (int) adjusted.bottom);
}

try {
croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options());
if (croppedImage != null && (rect.width() > outWidth || rect.height() > outHeight)) {
Matrix matrix = new Matrix();
Matrix matrix = new Matrix();
if (rect.width() > outWidth || rect.height() > outHeight) {
matrix.postScale((float) outWidth / rect.width(), (float) outHeight / rect.height());
croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true);
}
//If the picture's exifRotation !=0 ,they should be rotated to 0 degrees
//If the picture need not to be scale, they also need to be rotate to 0 degrees
matrix.postRotate(exifRotation);
croppedImage = Bitmap.createBitmap(croppedImage, 0, 0, croppedImage.getWidth(), croppedImage.getHeight(), matrix, true);
} catch (IllegalArgumentException e) {
// Rethrow with some extra information
throw new IllegalArgumentException("Rectangle " + rect + " is outside of the image ("
Expand Down Expand Up @@ -376,33 +386,35 @@ private void clearImageView() {
}

private void saveOutput(Bitmap croppedImage) {
if (saveUri != null) {
OutputStream outputStream = null;
try {
outputStream = getContentResolver().openOutputStream(saveUri);
int jpgQuality = 90;
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
if (extras.containsKey(Crop.Extra.JPG_QUALITY))
jpgQuality = extras.getInt(Crop.Extra.JPG_QUALITY);
}

OutputStream outputStream = null;
try {
if (saveUri != null) {
outputStream = this.getContentResolver().openOutputStream(saveUri);
if (outputStream != null) {
croppedImage.compress(Bitmap.CompressFormat.JPEG, 90, outputStream);
croppedImage.compress(Bitmap.CompressFormat.JPEG, jpgQuality, outputStream);
}
} catch (IOException e) {
setResultException(e);
Log.e("Cannot open file: " + saveUri, e);
} finally {
CropUtil.closeSilently(outputStream);
croppedImage.recycle();
}

CropUtil.copyExifRotation(
CropUtil.getFromMediaUri(this, getContentResolver(), sourceUri),
CropUtil.getFromMediaUri(this, getContentResolver(), saveUri)
);

setResultUri(saveUri);
} catch(IOException e) {
setResultException(e);
Log.e("Error saving file: " + saveUri, e);
} finally {
CropUtil.closeSilently(outputStream);
}

final Bitmap b = croppedImage;
handler.post(new Runnable() {
public void run() {
imageView.clear();
b.recycle();
}
});

Expand Down Expand Up @@ -433,5 +445,4 @@ private void setResultUri(Uri uri) {
private void setResultException(Throwable throwable) {
setResult(Crop.RESULT_ERROR, new Intent().putExtra(Crop.Extra.ERROR, throwable));
}

}
Loading