summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authornicolasroard <nicolasroard@google.com>2013-08-11 13:55:29 -0700
committernicolasroard <nicolasroard@google.com>2013-08-11 15:13:08 -0700
commit55d6abe58c3a7574a5d76c68ec5c21848848e399 (patch)
treea4b96fd123ab6a0c71a41366754329d89c15c54b /src
parentfc4700c0e9f1804d4b61bd586f066172a25c7035 (diff)
downloadandroid_packages_apps_Gallery2-55d6abe58c3a7574a5d76c68ec5c21848848e399.tar.gz
android_packages_apps_Gallery2-55d6abe58c3a7574a5d76c68ec5c21848848e399.tar.bz2
android_packages_apps_Gallery2-55d6abe58c3a7574a5d76c68ec5c21848848e399.zip
Fix export dialog (size export)
Change-Id: Ifa4bb6a990622bfc00f6b4fe4998417fec32e650
Diffstat (limited to 'src')
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java9
-rw-r--r--src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java4
-rw-r--r--src/com/android/gallery3d/filtershow/pipeline/ImageSavingTask.java9
-rw-r--r--src/com/android/gallery3d/filtershow/pipeline/ProcessingService.java14
-rw-r--r--src/com/android/gallery3d/filtershow/tools/SaveImage.java11
-rw-r--r--src/com/android/gallery3d/filtershow/ui/ExportDialog.java153
6 files changed, 188 insertions, 12 deletions
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java
index 8358e1a55..1cefe085e 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java
@@ -282,6 +282,15 @@ public final class GeometryMathUtils {
unpackGeometry(outHolder, geometry);
}
+ public static Rect finalGeometryRect(int width, int height,
+ Collection<FilterRepresentation> geometry) {
+ GeometryHolder holder = unpackGeometry(geometry);
+ RectF crop = getTrueCropRect(holder, width, height);
+ Rect frame = new Rect();
+ crop.roundOut(frame);
+ return frame;
+ }
+
private static Bitmap applyFullGeometryMatrix(Bitmap image, GeometryHolder holder) {
int width = image.getWidth();
int height = image.getHeight();
diff --git a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java
index e28cc356b..88e8d42e8 100644
--- a/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java
+++ b/src/com/android/gallery3d/filtershow/pipeline/ImagePreset.java
@@ -421,6 +421,10 @@ public class ImagePreset {
return null;
}
+ public Rect finalGeometryRect(int width, int height) {
+ return GeometryMathUtils.finalGeometryRect(width, height, getGeometryFilters());
+ }
+
public Bitmap applyGeometry(Bitmap bitmap, FilterEnvironment environment) {
// Apply any transform -- 90 rotate, flip, straighten, crop
// Returns a new bitmap.
diff --git a/src/com/android/gallery3d/filtershow/pipeline/ImageSavingTask.java b/src/com/android/gallery3d/filtershow/pipeline/ImageSavingTask.java
index b760edd5a..c29376f6e 100644
--- a/src/com/android/gallery3d/filtershow/pipeline/ImageSavingTask.java
+++ b/src/com/android/gallery3d/filtershow/pipeline/ImageSavingTask.java
@@ -18,6 +18,7 @@ package com.android.gallery3d.filtershow.pipeline;
import android.content.res.Resources;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.net.Uri;
import com.android.gallery3d.filtershow.cache.ImageLoader;
import com.android.gallery3d.filtershow.filters.FiltersManager;
@@ -35,6 +36,7 @@ public class ImageSavingTask extends ProcessingTask {
ImagePreset preset;
boolean flatten;
int quality;
+ float sizeFactor;
}
static class UpdateBitmap implements Update {
@@ -55,7 +57,8 @@ public class ImageSavingTask extends ProcessingTask {
}
public void saveImage(Uri sourceUri, Uri selectedUri,
- File destinationFile, ImagePreset preset, boolean flatten, int quality) {
+ File destinationFile, ImagePreset preset, boolean flatten,
+ int quality, float sizeFactor) {
SaveRequest request = new SaveRequest();
request.sourceUri = sourceUri;
request.selectedUri = selectedUri;
@@ -63,6 +66,7 @@ public class ImageSavingTask extends ProcessingTask {
request.preset = preset;
request.flatten = flatten;
request.quality = quality;
+ request.sizeFactor = sizeFactor;
postRequest(request);
}
@@ -89,7 +93,8 @@ public class ImageSavingTask extends ProcessingTask {
postUpdate(updateProgress);
}
});
- Uri uri = saveImage.processAndSaveImage(preset, !flatten, request.quality);
+ Uri uri = saveImage.processAndSaveImage(preset, !flatten,
+ request.quality, request.sizeFactor);
URIResult result = new URIResult();
result.uri = uri;
return result;
diff --git a/src/com/android/gallery3d/filtershow/pipeline/ProcessingService.java b/src/com/android/gallery3d/filtershow/pipeline/ProcessingService.java
index 4f736f868..518f232f9 100644
--- a/src/com/android/gallery3d/filtershow/pipeline/ProcessingService.java
+++ b/src/com/android/gallery3d/filtershow/pipeline/ProcessingService.java
@@ -32,7 +32,6 @@ import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.filters.FiltersManager;
import com.android.gallery3d.filtershow.filters.ImageFilter;
-import com.android.gallery3d.filtershow.imageshow.MasterImage;
import com.android.gallery3d.filtershow.tools.SaveImage;
import java.io.File;
@@ -51,6 +50,7 @@ public class ProcessingService extends Service {
private static final String DESTINATION_FILE = "destinationFile";
private static final String SAVING = "saving";
private static final String FLATTEN = "flatten";
+ private static final String SIZE_FACTOR = "sizeFactor";
private ProcessingTaskController mProcessingTaskController;
private ImageSavingTask mImageSavingTask;
@@ -139,13 +139,14 @@ public class ProcessingService extends Service {
}
public static Intent getSaveIntent(Context context, ImagePreset preset, File destination,
- Uri selectedImageUri, Uri sourceImageUri, boolean doFlatten, int quality) {
+ Uri selectedImageUri, Uri sourceImageUri, boolean doFlatten, int quality, float sizeFactor) {
Intent processIntent = new Intent(context, ProcessingService.class);
processIntent.putExtra(ProcessingService.SOURCE_URI,
sourceImageUri.toString());
processIntent.putExtra(ProcessingService.SELECTED_URI,
selectedImageUri.toString());
processIntent.putExtra(ProcessingService.QUALITY, quality);
+ processIntent.putExtra(ProcessingService.SIZE_FACTOR, sizeFactor);
if (destination != null) {
processIntent.putExtra(ProcessingService.DESTINATION_FILE, destination.toString());
}
@@ -192,6 +193,7 @@ public class ProcessingService extends Service {
String selected = intent.getStringExtra(SELECTED_URI);
String destination = intent.getStringExtra(DESTINATION_FILE);
int quality = intent.getIntExtra(QUALITY, 100);
+ float sizeFactor = intent.getFloatExtra(SIZE_FACTOR, 1);
boolean flatten = intent.getBooleanExtra(FLATTEN, false);
Uri sourceUri = Uri.parse(source);
Uri selectedUri = null;
@@ -206,7 +208,8 @@ public class ProcessingService extends Service {
preset.readJsonFromString(presetJson);
mNeedsAlive = false;
mSaving = true;
- handleSaveRequest(sourceUri, selectedUri, destinationFile, preset, flatten, quality);
+ handleSaveRequest(sourceUri, selectedUri, destinationFile, preset,
+ flatten, quality, sizeFactor);
}
return START_REDELIVER_INTENT;
}
@@ -224,7 +227,8 @@ public class ProcessingService extends Service {
}
public void handleSaveRequest(Uri sourceUri, Uri selectedUri,
- File destinationFile, ImagePreset preset, boolean flatten, int quality) {
+ File destinationFile, ImagePreset preset, boolean flatten,
+ int quality, float sizeFactor) {
mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationId++;
@@ -242,7 +246,7 @@ public class ProcessingService extends Service {
// Process the image
mImageSavingTask.saveImage(sourceUri, selectedUri, destinationFile,
- preset, flatten, quality);
+ preset, flatten, quality, sizeFactor);
}
public void updateNotificationWithBitmap(Bitmap bitmap) {
diff --git a/src/com/android/gallery3d/filtershow/tools/SaveImage.java b/src/com/android/gallery3d/filtershow/tools/SaveImage.java
index 83cbd0136..5aafbff33 100644
--- a/src/com/android/gallery3d/filtershow/tools/SaveImage.java
+++ b/src/com/android/gallery3d/filtershow/tools/SaveImage.java
@@ -310,7 +310,8 @@ public class SaveImage {
}
}
- public Uri processAndSaveImage(ImagePreset preset, boolean doAuxBackup, int quality) {
+ public Uri processAndSaveImage(ImagePreset preset, boolean doAuxBackup,
+ int quality, float sizeFactor) {
Uri uri = resetToOriginalImageIfNeeded(preset, doAuxBackup);
if (uri != null) {
@@ -341,6 +342,12 @@ public class SaveImage {
if (bitmap == null) {
return null;
}
+ if (sizeFactor != 1f) {
+ // if we have a valid size
+ int w = (int) (bitmap.getWidth() * sizeFactor);
+ int h = (int) (bitmap.getHeight() * sizeFactor);
+ bitmap = Bitmap.createScaledBitmap(bitmap, w, h, true);
+ }
updateProgress();
CachingPipeline pipeline = new CachingPipeline(FiltersManager.getManager(),
"Saving");
@@ -458,7 +465,7 @@ public class SaveImage {
Uri sourceImageUri = MasterImage.getImage().getUri();
Intent processIntent = ProcessingService.getSaveIntent(filterShowActivity, preset,
- destination, selectedImageUri, sourceImageUri, false, 90);
+ destination, selectedImageUri, sourceImageUri, false, 90, 1f);
filterShowActivity.startService(processIntent);
diff --git a/src/com/android/gallery3d/filtershow/ui/ExportDialog.java b/src/com/android/gallery3d/filtershow/ui/ExportDialog.java
index 4b30e7b18..b0046e1bb 100644
--- a/src/com/android/gallery3d/filtershow/ui/ExportDialog.java
+++ b/src/com/android/gallery3d/filtershow/ui/ExportDialog.java
@@ -17,40 +17,112 @@
package com.android.gallery3d.filtershow.ui;
import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.support.v4.app.DialogFragment;
+import android.text.Editable;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TextView;
import com.android.gallery3d.R;
import com.android.gallery3d.filtershow.FilterShowActivity;
import com.android.gallery3d.filtershow.imageshow.MasterImage;
+import com.android.gallery3d.filtershow.pipeline.ImagePreset;
import com.android.gallery3d.filtershow.pipeline.ProcessingService;
import com.android.gallery3d.filtershow.tools.SaveImage;
+import java.io.ByteArrayOutputStream;
import java.io.File;
-public class ExportDialog extends DialogFragment implements View.OnClickListener, SeekBar.OnSeekBarChangeListener{
+public class ExportDialog extends DialogFragment implements View.OnClickListener,
+ SeekBar.OnSeekBarChangeListener {
SeekBar mSeekBar;
TextView mSeekVal;
+ EditText mWidthText;
+ EditText mHeightText;
+ TextView mEstimatedSize;
+ int mQuality = 95;
+ int mExportWidth = 0;
+ int mExportHeight = 0;
+ Rect mOriginalBounds;
+ int mCompressedSize;
+ Rect mCompressedBounds;
+ float mExportCompressionMargin = 1.1f;
+ float mRatio;
String mSliderLabel;
+ boolean mEditing = false;
+ Handler mHandler;
+ int mUpdateDelay = 1000;
+ Runnable mUpdateRunnable = new Runnable() {
+ @Override
+ public void run() {
+ updateCompressionFactor();
+ updateSize();
+ }
+ };
+
+ private class Watcher implements TextWatcher {
+ private EditText mEditText;
+ Watcher(EditText text) {
+ mEditText = text;
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ textChanged(mEditText);
+ }
+ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
+ mHandler = new Handler(getActivity().getMainLooper());
+
View view = inflater.inflate(R.layout.filtershow_export_dialog, container);
mSeekBar = (SeekBar) view.findViewById(R.id.qualitySeekBar);
mSeekVal = (TextView) view.findViewById(R.id.qualityTextView);
mSliderLabel = getString(R.string.quality) + ": ";
+ mSeekBar.setProgress(mQuality);
mSeekVal.setText(mSliderLabel + mSeekBar.getProgress());
mSeekBar.setOnSeekBarChangeListener(this);
+ mWidthText = (EditText) view.findViewById(R.id.editableWidth);
+ mHeightText = (EditText) view.findViewById(R.id.editableHeight);
+ mEstimatedSize = (TextView) view.findViewById(R.id.estimadedSize);
+
+ mOriginalBounds = MasterImage.getImage().getOriginalBounds();
+ ImagePreset preset = MasterImage.getImage().getPreset();
+ mOriginalBounds = preset.finalGeometryRect(mOriginalBounds.width(),
+ mOriginalBounds.height());
+ mRatio = mOriginalBounds.width() / (float) mOriginalBounds.height();
+ mWidthText.setText("" + mOriginalBounds.width());
+ mHeightText.setText("" + mOriginalBounds.height());
+ mExportWidth = mOriginalBounds.width();
+ mExportHeight = mOriginalBounds.height();
+ mWidthText.addTextChangedListener(new Watcher(mWidthText));
+ mHeightText.addTextChangedListener(new Watcher(mHeightText));
+
view.findViewById(R.id.cancel).setOnClickListener(this);
view.findViewById(R.id.done).setOnClickListener(this);
getDialog().setTitle(R.string.export_flattened);
+
+ updateCompressionFactor();
+ updateSize();
return view;
}
@@ -61,12 +133,19 @@ public class ExportDialog extends DialogFragment implements View.OnClickListener
@Override
public void onStartTrackingTouch(SeekBar arg0) {
- // Do nothing
+ // Do nothing
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
mSeekVal.setText(mSliderLabel + arg1);
+ mQuality = mSeekBar.getProgress();
+ scheduleUpdateCompressionFactor();
+ }
+
+ private void scheduleUpdateCompressionFactor() {
+ mHandler.removeCallbacks(mUpdateRunnable);
+ mHandler.postDelayed(mUpdateRunnable, mUpdateDelay);
}
@Override
@@ -79,12 +158,80 @@ public class ExportDialog extends DialogFragment implements View.OnClickListener
FilterShowActivity activity = (FilterShowActivity) getActivity();
Uri sourceUri = MasterImage.getImage().getUri();
File dest = SaveImage.getNewFile(activity, sourceUri);
+ float scaleFactor = mExportWidth / (float) mOriginalBounds.width();
Intent processIntent = ProcessingService.getSaveIntent(activity, MasterImage
.getImage().getPreset(), dest, activity.getSelectedImageUri(), sourceUri,
- true, mSeekBar.getProgress());
+ true, mSeekBar.getProgress(), scaleFactor);
activity.startService(processIntent);
dismiss();
break;
}
}
+
+ public void updateCompressionFactor() {
+ Bitmap bitmap = MasterImage.getImage().getFilteredImage();
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ bitmap.compress(Bitmap.CompressFormat.JPEG, mQuality, out);
+ mCompressedSize = out.size();
+ mCompressedBounds = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
+ }
+
+ public void updateSize() {
+ if (mCompressedBounds == null) {
+ return;
+ }
+ // This is a rough estimate of the final save size. There's some loose correlation
+ // between a compressed jpeg and a larger version of it in function of the image
+ // area. Not a perfect estimate by far.
+ float originalArea = mCompressedBounds.width() * mCompressedBounds.height();
+ float newArea = mExportWidth * mExportHeight;
+ float factor = originalArea / (float) mCompressedSize;
+ float compressedSize = newArea / factor;
+ compressedSize *= mExportCompressionMargin;
+ float size = compressedSize / 1024.f / 1024.f;
+ size = ((int) (size * 100)) / 100f;
+ String estimatedSize = "" + size + " Mb";
+ mEstimatedSize.setText(estimatedSize);
+ }
+
+ private void textChanged(EditText text) {
+ if (mEditing) {
+ return;
+ }
+ mEditing = true;
+ int width = 0;
+ int height = 0;
+ if (text.getId() == R.id.editableWidth) {
+ if (mWidthText.getText() != null) {
+ String value = String.valueOf(mWidthText.getText());
+ if (value.length() > 0) {
+ width = Integer.parseInt(value);
+ if (width > mOriginalBounds.width()) {
+ width = mOriginalBounds.width();
+ mWidthText.setText("" + width);
+ }
+ height = (int) (width / mRatio);
+ }
+ mHeightText.setText("" + height);
+ }
+ } else if (text.getId() == R.id.editableHeight) {
+ if (mHeightText.getText() != null) {
+ String value = String.valueOf(mHeightText.getText());
+ if (value.length() > 0) {
+ height = Integer.parseInt(value);
+ if (height > mOriginalBounds.height()) {
+ height = mOriginalBounds.height();
+ mHeightText.setText("" + height);
+ }
+ width = (int) (height * mRatio);
+ }
+ mWidthText.setText("" + width);
+ }
+ }
+ mExportWidth = width;
+ mExportHeight = height;
+ updateSize();
+ mEditing = false;
+ }
+
}