Skip to content

Commit 7359a4b

Browse files
committedMay 30, 2022
[Update] compress file
1 parent bf010e3 commit 7359a4b

File tree

4 files changed

+338
-8
lines changed

4 files changed

+338
-8
lines changed
 

‎.idea/uiDesigner.xml

+124
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎picker/build.gradle

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55

66
group = 'io.kredibel' // <-- group name
77
archivesBaseName = "picker" // <-- artifact name
8-
version = "0.0.1"
8+
version = "0.0.3"
99

1010
publishing {
1111

@@ -37,10 +37,10 @@ android {
3737
compileSdk 31
3838

3939
defaultConfig {
40-
minSdk 24
40+
minSdk 19
4141
targetSdk 31
4242
versionCode 1
43-
versionName "1.0"
43+
versionName project.version
4444

4545
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
4646
consumerProguardFiles "consumer-rules.pro"
@@ -62,6 +62,7 @@ dependencies {
6262

6363
implementation 'androidx.appcompat:appcompat:1.4.1'
6464
implementation 'com.google.android.material:material:1.6.0'
65+
implementation 'androidx.exifinterface:exifinterface:1.3.2'
6566
testImplementation 'junit:junit:4.13.2'
6667
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
6768
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
package io.kredibel.picker;
2+
3+
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.database.Cursor;
7+
import android.graphics.Bitmap;
8+
import android.graphics.BitmapFactory;
9+
import android.graphics.Matrix;
10+
import android.net.Uri;
11+
import android.provider.MediaStore;
12+
import androidx.exifinterface.media.ExifInterface;
13+
14+
import java.io.File;
15+
import java.io.FileOutputStream;
16+
import java.io.IOException;
17+
import java.io.InputStream;
18+
import java.util.Objects;
19+
20+
public class Compressor {
21+
//max width and height values of the compressed image is taken as 612x816
22+
private int maxWidth = 612;
23+
private int maxHeight = 816;
24+
private Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
25+
private int quality = 50;
26+
private String destinationDirectoryPath;
27+
28+
private Context ctx;
29+
30+
public Compressor(Context context) {
31+
this.ctx = context;
32+
destinationDirectoryPath = context.getCacheDir().getPath() + File.separator + "images";
33+
}
34+
35+
public static Bitmap getBitmapData(Context context, Intent data) {
36+
Uri photoUri = null;
37+
if (data != null && data.getData() != null) {
38+
photoUri = data.getData();
39+
}
40+
41+
//String path = photoUri.getPath();
42+
43+
try {
44+
InputStream imageStream = context.getContentResolver().openInputStream(photoUri);
45+
Bitmap bitmap = BitmapFactory.decodeStream(imageStream);
46+
imageStream.close();
47+
return bitmap;
48+
} catch (IOException e) {
49+
e.printStackTrace();
50+
return null;
51+
}
52+
}
53+
54+
static File compressImage(File imageFile, int reqWidth, int reqHeight, Bitmap.CompressFormat compressFormat, int quality, String destinationPath) throws IOException {
55+
FileOutputStream fileOutputStream = null;
56+
File file = new File(destinationPath).getParentFile();
57+
if (!Objects.requireNonNull(file).exists()) {
58+
file.mkdirs();
59+
}
60+
try {
61+
fileOutputStream = new FileOutputStream(destinationPath);
62+
// write the compressed bitmap at the destination specified by destinationPath.
63+
decodeSampledBitmapFromFile(imageFile, reqWidth, reqHeight).compress(compressFormat, quality, fileOutputStream);
64+
} finally {
65+
if (fileOutputStream != null) {
66+
fileOutputStream.flush();
67+
fileOutputStream.close();
68+
}
69+
}
70+
return new File(destinationPath);
71+
}
72+
73+
static Bitmap decodeSampledBitmapFromFile(File imageFile, int reqWidth, int reqHeight) throws IOException {
74+
// First decode with inJustDecodeBounds=true to check dimensions
75+
BitmapFactory.Options options = new BitmapFactory.Options();
76+
options.inJustDecodeBounds = true;
77+
BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
78+
// Calculate inSampleSize
79+
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
80+
// Decode bitmap with inSampleSize set
81+
options.inJustDecodeBounds = false;
82+
Bitmap scaledBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
83+
//check the rotation of the image and display it properly
84+
ExifInterface exif;
85+
exif = new ExifInterface(imageFile.getAbsolutePath());
86+
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
87+
Matrix matrix = new Matrix();
88+
if (orientation == 6) {
89+
matrix.postRotate(90);
90+
} else if (orientation == 3) {
91+
matrix.postRotate(180);
92+
} else if (orientation == 8) {
93+
matrix.postRotate(270);
94+
}
95+
scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
96+
return scaledBitmap;
97+
}
98+
99+
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
100+
// Raw height and width of image
101+
final int height = options.outHeight;
102+
final int width = options.outWidth;
103+
int inSampleSize = 1;
104+
if (height > reqHeight || width > reqWidth) {
105+
final int halfHeight = height / 2;
106+
final int halfWidth = width / 2;
107+
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
108+
// height and width larger than the requested height and width.
109+
while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
110+
inSampleSize *= 2;
111+
}
112+
}
113+
return inSampleSize;
114+
}
115+
116+
public String getRealPathFromUri(Uri contentUri) {
117+
Cursor cursor = null;
118+
try {
119+
String[] proj = {MediaStore.Images.Media.DATA};
120+
cursor = ctx.getContentResolver().query(contentUri, proj, null, null, null);
121+
assert cursor != null;
122+
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
123+
cursor.moveToFirst();
124+
return cursor.getString(column_index);
125+
} finally {
126+
if (cursor != null) {
127+
cursor.close();
128+
}
129+
}
130+
}
131+
132+
public Compressor setMaxWidth(int maxWidth) {
133+
this.maxWidth = maxWidth;
134+
return this;
135+
}
136+
137+
public Compressor setMaxHeight(int maxHeight) {
138+
this.maxHeight = maxHeight;
139+
return this;
140+
}
141+
142+
public Compressor setCompressFormat(Bitmap.CompressFormat compressFormat) {
143+
this.compressFormat = compressFormat;
144+
return this;
145+
}
146+
147+
public Compressor setQuality(int quality) {
148+
this.quality = quality;
149+
return this;
150+
}
151+
152+
/*public Flowable<File> compressToFileAsFlowable(final File imageFile) {
153+
return compressToFileAsFlowable(imageFile, imageFile.getName());
154+
}
155+
public Flowable<File> compressToFileAsFlowable(final File imageFile,
156+
final String compressedFileName) {
157+
return Flowable.defer((Callable<Flowable<File>>) () -> {
158+
try {
159+
return Flowable.just(compressToFile(imageFile, compressedFileName));
160+
} catch (IOException e) {
161+
return Flowable.error(e);
162+
}
163+
});
164+
}
165+
public Flowable<Bitmap> compressToBitmapAsFlowable(final File imageFile) {
166+
return Flowable.defer((Callable<Flowable<Bitmap>>) () -> {
167+
try {
168+
return Flowable.just(compressToBitmap(imageFile));
169+
} catch (IOException e) {
170+
return Flowable.error(e);
171+
}
172+
});
173+
}*/
174+
175+
public Compressor setDestinationDirectoryPath(String destinationDirectoryPath) {
176+
this.destinationDirectoryPath = destinationDirectoryPath;
177+
return this;
178+
}
179+
180+
public File compressUritoFile(Uri uri) throws IOException {
181+
return compressToFile(new File(getRealPathFromUri(uri)));
182+
}
183+
184+
public File compressToFile(File imageFile) throws IOException {
185+
return compressToFile(imageFile, imageFile.getName());
186+
}
187+
188+
public File compressToFile(File imageFile, String compressedFileName) throws IOException {
189+
return compressImage(imageFile, maxWidth, maxHeight, compressFormat, quality, destinationDirectoryPath + File.separator + compressedFileName);
190+
}
191+
192+
public Bitmap compressToBitmap(File imageFile) throws IOException {
193+
return decodeSampledBitmapFromFile(imageFile, maxWidth, maxHeight);
194+
}
195+
}

‎picker/src/main/java/io/kredibel/picker/PickerObserver.java

+15-5
Original file line numberDiff line numberDiff line change
@@ -33,23 +33,31 @@
3333
public class PickerObserver implements DefaultLifecycleObserver {
3434
private final ActivityResultRegistry registry;
3535
private final Activity activity;
36+
private final Compressor compressor;
3637
private PickerListener pickerListener;
37-
ActivityResultCallback<Uri> activityResultUri = new ActivityResultCallback<Uri>() {
38+
ActivityResultCallback<Uri> galleryResultUri = new ActivityResultCallback<Uri>() {
3839
@Override
3940
public void onActivityResult(Uri uri) {
4041
if (uri != null) {
41-
pickerListener.onPicked(uri, new File(uri.getPath()), uriToBitmap(uri));
42+
try {
43+
File file = compressor.compressUritoFile(uri);
44+
pickerListener.onPicked(uri, file, uriToBitmap(uri));
45+
} catch (IOException e) {
46+
throw new RuntimeException(e);
47+
}
48+
4249
}
4350
}
4451
};
45-
ActivityResultCallback<ActivityResult> activityResultIntent = new ActivityResultCallback<ActivityResult>() {
52+
ActivityResultCallback<ActivityResult> cameraResultIntent = new ActivityResultCallback<ActivityResult>() {
4653
@Override
4754
public void onActivityResult(ActivityResult result) {
4855
int resultCode = result.getResultCode();
4956
Intent data = result.getData();
5057
if (resultCode == RESULT_OK && data != null) {
5158
Bundle bundle = data.getExtras();
5259
Bitmap bitmap = (Bitmap) bundle.get("data");
60+
//File file = compressor.compressToFile()
5361

5462
ContextWrapper cw = new ContextWrapper(activity.getApplicationContext());
5563
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
@@ -76,20 +84,22 @@ public void onActivityResult(ActivityResult result) {
7684
private ActivityResultLauncher<Intent> cameraLauncher;
7785

7886
public PickerObserver(@NonNull AppCompatActivity activity) {
87+
this.compressor = new Compressor(activity);
7988
this.activity = activity;
8089
this.registry = activity.getActivityResultRegistry();
8190
}
8291

8392
public PickerObserver(@NonNull Fragment fr) {
8493
this.activity = fr.requireActivity();
94+
this.compressor = new Compressor(this.activity);
8595
this.registry = fr.requireActivity().getActivityResultRegistry();
8696
}
8797

8898
@Override
8999
public void onCreate(@NonNull LifecycleOwner owner) {
90100
DefaultLifecycleObserver.super.onCreate(owner);
91-
imageLauncher = registry.register("key", owner, new ActivityResultContracts.GetContent(), activityResultUri);
92-
cameraLauncher = registry.register("key1", owner, new ActivityResultContracts.StartActivityForResult(), activityResultIntent);
101+
imageLauncher = registry.register("key", owner, new ActivityResultContracts.GetContent(), galleryResultUri);
102+
cameraLauncher = registry.register("key1", owner, new ActivityResultContracts.StartActivityForResult(), cameraResultIntent);
93103
}
94104

95105
private Bitmap uriToBitmap(Uri selectedFileUri) {

0 commit comments

Comments
 (0)
Please sign in to comment.