Skip to content
This repository was archived by the owner on May 31, 2023. It is now read-only.
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
10 changes: 7 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ version '1.0-SNAPSHOT'
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}

dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath 'com.android.tools.build:gradle:3.3.3'
}
}

rootProject.allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

Expand All @@ -33,3 +33,7 @@ android {
abortOnError false
}
}

dependencies {
implementation 'androidx.exifinterface:exifinterface:1.3.5'
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ExifInterface;
import androidx.exifinterface.media.ExifInterface;
import android.util.Log;

import java.io.ByteArrayOutputStream;
Expand All @@ -22,158 +22,195 @@
public class MethodCallHandlerImpl implements MethodChannel.MethodCallHandler {
private final Context context;

static final List<String> ExifAttributes = Arrays.asList(
"FNumber",
"ExposureTime",
"ISOSpeedRatings",
"GPSAltitude",
"GPSAltitudeRef",
"FocalLength",
"GPSDateStamp",
"WhiteBalance",
"GPSProcessingMethod",
"GPSTimeStamp",
"DateTime",
"Flash",
"GPSLatitude",
"GPSLatitudeRef",
"GPSLongitude",
"GPSLongitudeRef",
"Make",
"Model",
"Orientation");

MethodCallHandlerImpl(Context context) {
this.context = context;
}

@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
if(call.method.equals("compressImage")) {
if (call.method.equals("compressImage")) {
String fileName = call.argument("file");
int resizePercentage = call.argument("percentage");
int targetWidth = call.argument("targetWidth") == null ? 0 : (int) call.argument("targetWidth");
int targetHeight = call.argument("targetHeight") == null ? 0 : (int) call.argument("targetHeight");
int quality = call.argument("quality");

File file = new File(fileName);
compressImage(result, fileName, resizePercentage, targetWidth, targetHeight, quality);
} else if (call.method.equals("getImageProperties")) {
String fileName = call.argument("file");

if(!file.exists()) {
result.error("file does not exist", fileName, null);
return;
}
getImageProperties(result, fileName);
} else if (call.method.equals("cropImage")) {
String fileName = call.argument("file");
int originX = call.argument("originX");
int originY = call.argument("originY");
int width = call.argument("width");
int height = call.argument("height");

Bitmap bmp = BitmapFactory.decodeFile(fileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
cropImage(result, fileName, originX, originY, width, height);
} else if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}

int newWidth = targetWidth == 0 ? (bmp.getWidth() / 100 * resizePercentage) : targetWidth;
int newHeight = targetHeight == 0 ? (bmp.getHeight() / 100 * resizePercentage) : targetHeight;
private void compressImage(MethodChannel.Result result, String fileName, int resizePercentage, int targetWidth, int targetHeight, int quality) {
File file = new File(fileName);

bmp = Bitmap.createScaledBitmap(
bmp, newWidth, newHeight, true);
if (!file.exists()) {
result.error("file does not exist", fileName, null);
return;
}

// reconfigure bitmap to use RGB_565 before compressing
// fixes https://github.com/btastic/flutter_native_image/issues/47
Bitmap newBmp = bmp.copy(Bitmap.Config.RGB_565, false);
newBmp.compress(Bitmap.CompressFormat.JPEG, quality, bos);
Bitmap bmp = BitmapFactory.decodeFile(fileName);
if (bmp == null) {
result.error("File could not be decoded by BitmapFactory", fileName, null);
return;
}

try {
String outputFileName = File.createTempFile(
getFilenameWithoutExtension(file).concat("_compressed"),
".jpg",
context.getExternalCacheDir()
).getPath();
int newWidth = targetWidth == 0 ? (bmp.getWidth() / 100 * resizePercentage) : targetWidth;
int newHeight = targetHeight == 0 ? (bmp.getHeight() / 100 * resizePercentage) : targetHeight;

OutputStream outputStream = new FileOutputStream(outputFileName);
bos.writeTo(outputStream);
bmp = Bitmap.createScaledBitmap(bmp, newWidth, newHeight, true);

copyExif(fileName, outputFileName);
// reconfigure bitmap to use RGB_565 before compressing
// fixes https://github.com/btastic/flutter_native_image/issues/47
Bitmap newBmp = bmp.copy(Bitmap.Config.RGB_565, false);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
newBmp.compress(Bitmap.CompressFormat.JPEG, quality, bos);

result.success(outputFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
result.error("file does not exist", fileName, null);
} catch (IOException e) {
e.printStackTrace();
result.error("something went wrong", fileName, null);
OutputStream outputStream = null;
try {
String outputFileName = File.createTempFile(
getFilenameWithoutExtension(file).concat("_compressed"),
".jpg",
context.getExternalCacheDir()
).getPath();

outputStream = new FileOutputStream(outputFileName);
bos.writeTo(outputStream);

copyExif (fileName, outputFileName);

result.success(outputFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
result.error("file does not exist", fileName, null);
} catch (IOException e) {
e.printStackTrace();
result.error("something went wrong", fileName, null);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

private void getImageProperties(MethodChannel.Result result, String fileName) {
File file = new File(fileName);

if (!file.exists()) {
result.error("file does not exist", fileName, null);
return;
}
if(call.method.equals("getImageProperties")) {
String fileName = call.argument("file");
File file = new File(fileName);

if(!file.exists()) {
result.error("file does not exist", fileName, null);
return;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName,options);
HashMap<String, Integer> properties = new HashMap<String, Integer>();
properties.put("width", options.outWidth);
properties.put("height", options.outHeight);

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(fileName,options);
HashMap<String, Integer> properties = new HashMap<String, Integer>();
properties.put("width", options.outWidth);
properties.put("height", options.outHeight);

int orientation = ExifInterface.ORIENTATION_UNDEFINED;
try {
ExifInterface exif = new ExifInterface(fileName);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
} catch(IOException ex) {
// EXIF could not be read from the file; ignore
}
properties.put("orientation", orientation);
int orientation = ExifInterface.ORIENTATION_UNDEFINED;
try {
ExifInterface exif = new ExifInterface(fileName);
orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
} catch (IOException ex) {
// EXIF could not be read from the file; ignore
}
properties.put("orientation", orientation);

result.success(properties);
}

private void cropImage(MethodChannel.Result result, String fileName, int originX, int originY, int width, int height) {
File file = new File(fileName);

result.success(properties);
if (!file.exists()) {
result.error("file does not exist", fileName, null);
return;
}
if(call.method.equals("cropImage")) {
String fileName = call.argument("file");
int originX = call.argument("originX");
int originY = call.argument("originY");
int width = call.argument("width");
int height = call.argument("height");

File file = new File(fileName);
Boolean isPNG = fileName.toLowerCase().endsWith(".png");
Bitmap.CompressFormat format = isPNG ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG;
String extension = isPNG ? ".png" : ".jpg";

if(!file.exists()) {
result.error("file does not exist", fileName, null);
return;
}
Boolean isPNG = fileName.toLowerCase().endsWith(".png");
Bitmap.CompressFormat format = isPNG ? Bitmap.CompressFormat.PNG : Bitmap.CompressFormat.JPEG;
String extension = isPNG ? ".png" : ".jpg";

Bitmap bmp = BitmapFactory.decodeFile(fileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
bmp = Bitmap.createBitmap(bmp, originX, originY, width, height);
} catch(IllegalArgumentException e) {
e.printStackTrace();
result.error("bounds are outside of the dimensions of the source image", fileName, null);
}
Bitmap bmp = BitmapFactory.decodeFile(fileName);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
bmp = Bitmap.createBitmap(bmp, originX, originY, width, height);
} catch (IllegalArgumentException e) {
e.printStackTrace();
result.error("bounds are outside of the dimensions of the source image", fileName, null);
}

bmp.compress(format, 100, bos);
bmp.recycle();
OutputStream outputStream = null;
try {
String outputFileName = File.createTempFile(
getFilenameWithoutExtension(file).concat("_cropped"),
extension,
context.getExternalCacheDir()
).getPath();


outputStream = new FileOutputStream(outputFileName);
bos.writeTo(outputStream);

copyExif(fileName, outputFileName);

result.success(outputFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
result.error("file does not exist", fileName, null);
} catch (IOException e) {
e.printStackTrace();
result.error("something went wrong", fileName, null);
}finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
bmp.compress(format, 100, bos);
bmp.recycle();

OutputStream outputStream = null;
try {
String outputFileName = File.createTempFile(
getFilenameWithoutExtension(file).concat("_cropped"),
extension,
context.getExternalCacheDir()
).getPath();

outputStream = new FileOutputStream(outputFileName);
bos.writeTo(outputStream);

copyExif(fileName, outputFileName);

result.success(outputFileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
result.error("file does not exist", fileName, null);
} catch (IOException e) {
e.printStackTrace();
result.error("something went wrong", fileName, null);
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}



return;
}
if (call.method.equals("getPlatformVersion")) {
result.success("Android " + android.os.Build.VERSION.RELEASE);
} else {
result.notImplemented();
}
}

Expand All @@ -182,28 +219,7 @@ private void copyExif(String filePathOri, String filePathDest) {
ExifInterface oldExif = new ExifInterface(filePathOri);
ExifInterface newExif = new ExifInterface(filePathDest);

List<String> attributes =
Arrays.asList(
"FNumber",
"ExposureTime",
"ISOSpeedRatings",
"GPSAltitude",
"GPSAltitudeRef",
"FocalLength",
"GPSDateStamp",
"WhiteBalance",
"GPSProcessingMethod",
"GPSTimeStamp",
"DateTime",
"Flash",
"GPSLatitude",
"GPSLatitudeRef",
"GPSLongitude",
"GPSLongitudeRef",
"Make",
"Model",
"Orientation");
for (String attribute : attributes) {
for (String attribute : ExifAttributes) {
setIfNotNull(oldExif, newExif, attribute);
}

Expand All @@ -220,11 +236,6 @@ private void setIfNotNull(ExifInterface oldExif, ExifInterface newExif, String p
}
}

private static String pathComponent(String filename) {
int i = filename.lastIndexOf(File.separator);
return (i > -1) ? filename.substring(0, i) : filename;
}

private static String getFilenameWithoutExtension(File file) {
String fileName = file.getName();

Expand Down