summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--jni/filters/geometry.c68
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java126
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java10
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java18
-rw-r--r--src/com/android/gallery3d/filtershow/imageshow/ImageShow.java5
5 files changed, 206 insertions, 21 deletions
diff --git a/jni/filters/geometry.c b/jni/filters/geometry.c
index f2f5b27bc..8550dd778 100644
--- a/jni/filters/geometry.c
+++ b/jni/filters/geometry.c
@@ -19,14 +19,18 @@
void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterFlip, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint flip) {
char* destination = 0;
char* source = 0;
+ int len = dstWidth * dstHeight * 4;
+ if (srcWidth != dstWidth || srcHeight != dstHeight) {
+ return;
+ }
AndroidBitmap_lockPixels(env, src, (void**) &source);
AndroidBitmap_lockPixels(env, dst, (void**) &destination);
int i = 0;
- for (; i < dstWidth * dstHeight * 4; i+=4) {
+ for (; i < len; i += 4) {
int r = source[RED];
int g = source[GREEN];
int b = source[BLUE];
-
+ // TODO: implement flip
destination[RED] = 255;
destination[GREEN] = g;
destination[BLUE] = b;
@@ -34,3 +38,63 @@ void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterFlip, jobject src, jint srcW
AndroidBitmap_unlockPixels(env, dst);
AndroidBitmap_unlockPixels(env, src);
}
+
+void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterRotate, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jfloat rotate) {
+ char* destination = 0;
+ char* source = 0;
+ int len = dstWidth * dstHeight * 4;
+ AndroidBitmap_lockPixels(env, src, (void**) &source);
+ AndroidBitmap_lockPixels(env, dst, (void**) &destination);
+ // TODO: implement rotate
+ int i = 0;
+ for (; i < len; i += 4) {
+ int r = source[RED];
+ int g = source[GREEN];
+ int b = source[BLUE];
+ destination[RED] = r;
+ destination[GREEN] = 255;
+ destination[BLUE] = b;
+ }
+ AndroidBitmap_unlockPixels(env, dst);
+ AndroidBitmap_unlockPixels(env, src);
+}
+
+void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterCrop, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jint offsetWidth, jint offsetHeight) {
+ char* destination = 0;
+ char* source = 0;
+ int len = dstWidth * dstHeight * 4;
+ AndroidBitmap_lockPixels(env, src, (void**) &source);
+ AndroidBitmap_lockPixels(env, dst, (void**) &destination);
+ // TODO: implement crop
+ int i = 0;
+ for (; i < len; i += 4) {
+ int r = source[RED];
+ int g = source[GREEN];
+ int b = source[BLUE];
+ destination[RED] = r;
+ destination[GREEN] = g;
+ destination[BLUE] = 255;
+ }
+ AndroidBitmap_unlockPixels(env, dst);
+ AndroidBitmap_unlockPixels(env, src);
+}
+
+void JNIFUNCF(ImageFilterGeometry, nativeApplyFilterStraighten, jobject src, jint srcWidth, jint srcHeight, jobject dst, jint dstWidth, jint dstHeight, jfloat straightenAngle) {
+ char* destination = 0;
+ char* source = 0;
+ int len = dstWidth * dstHeight * 4;
+ AndroidBitmap_lockPixels(env, src, (void**) &source);
+ AndroidBitmap_lockPixels(env, dst, (void**) &destination);
+ // TODO: implement straighten
+ int i = 0;
+ for (; i < len; i += 4) {
+ int r = source[RED];
+ int g = source[GREEN];
+ int b = source[BLUE];
+ destination[RED] = 128;
+ destination[GREEN] = g;
+ destination[BLUE] = 128;
+ }
+ AndroidBitmap_unlockPixels(env, dst);
+ AndroidBitmap_unlockPixels(env, src);
+}
diff --git a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
index 69a8f20d8..1368255a6 100644
--- a/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
+++ b/src/com/android/gallery3d/filtershow/filters/ImageFilterGeometry.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
package com.android.gallery3d.filtershow.filters;
@@ -5,13 +20,21 @@ import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.Log;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
import com.android.gallery3d.filtershow.imageshow.GeometryMetadata.FLIP;
+import com.android.gallery3d.filtershow.imageshow.ImageGeometry;
public class ImageFilterGeometry extends ImageFilter {
private final Bitmap.Config mConfig = Bitmap.Config.ARGB_8888;
private GeometryMetadata mGeometry = null;
+ private static final String LOGTAG = "ImageFilterGeometry";
+ private static final boolean LOGV = false;
+ private static final int BOTH = 3;
+ private static final int VERTICAL = 2;
+ private static final int HORIZONTAL = 1;
public ImageFilterGeometry() {
mName = "Geometry";
@@ -23,22 +46,109 @@ public class ImageFilterGeometry extends ImageFilter {
return filter;
}
- public void setGeometryMetadata(GeometryMetadata m){
+ public void setGeometryMetadata(GeometryMetadata m) {
mGeometry = m;
}
native protected void nativeApplyFilterFlip(Bitmap src, int srcWidth, int srcHeight,
Bitmap dst, int dstWidth, int dstHeight, int flip);
+ native protected void nativeApplyFilterRotate(Bitmap src, int srcWidth, int srcHeight,
+ Bitmap dst, int dstWidth, int dstHeight, float rotate);
+
+ native protected void nativeApplyFilterCrop(Bitmap src, int srcWidth, int srcHeight,
+ Bitmap dst, int dstWidth, int dstHeight, int offsetWidth, int offsetHeight);
+
+ native protected void nativeApplyFilterStraighten(Bitmap src, int srcWidth, int srcHeight,
+ Bitmap dst, int dstWidth, int dstHeight, float straightenAngle);
+
@Override
- public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
- if(mGeometry.getFlipType() == FLIP.NONE){
- return bitmap;
+ public Bitmap apply(Bitmap originalBitmap, float scaleFactor, boolean highQuality) {
+ Rect cropBounds = new Rect();
+ Rect originalBounds = new Rect();
+ FLIP flipType = mGeometry.getFlipType();
+ float rAngle = mGeometry.getRotation();
+ float sAngle = mGeometry.getStraightenRotation();
+ mGeometry.getCropBounds().roundOut(cropBounds);
+ mGeometry.getPhotoBounds().roundOut(originalBounds);
+ boolean flip = flipType != FLIP.NONE;
+ boolean rotate = rAngle != 0;
+ boolean crop = !cropBounds.equals(originalBounds);
+ boolean straighten = sAngle != 0;
+
+ int jniFlipType = 0;
+ switch (flipType) {
+ case BOTH:
+ jniFlipType = BOTH;
+ break;
+ case VERTICAL:
+ jniFlipType = VERTICAL;
+ break;
+ case HORIZONTAL:
+ jniFlipType = HORIZONTAL;
+ break;
+ default:
+ jniFlipType = 0;
+ break;
+ }
+ int bmWidth = originalBitmap.getWidth();
+ int bmHeight = originalBitmap.getHeight();
+ if (!(flip || rotate || crop || straighten)) {
+ return originalBitmap;
+ }
+ if (originalBounds.width() != bmWidth || originalBounds.height() != bmHeight) {
+ if (LOGV)
+ Log.v(LOGTAG, "PHOTOBOUNDS WIDTH/HEIGHT NOT SAME AS BITMAP WIDTH/HEIGHT");
+ return originalBitmap;
+ }
+ Bitmap modBitmap = originalBitmap;
+ Rect modifiedBounds = new Rect(originalBounds);
+ if (flip) {
+ modBitmap = originalBitmap.copy(mConfig, true);
+ nativeApplyFilterFlip(originalBitmap, bmWidth, bmHeight, modBitmap,
+ bmWidth, bmHeight, jniFlipType);
+ }
+ if (rotate) {
+ // Fails for non-90 degree rotations
+ Bitmap modBitmapRotate = null;
+ if (((int) (sAngle / 90)) % 2 == 0) {
+ modBitmapRotate = Bitmap.createBitmap(bmWidth, bmHeight, mConfig);
+ nativeApplyFilterRotate(modBitmap, bmWidth, bmHeight, modBitmapRotate,
+ bmWidth, bmHeight, mGeometry.getRotation());
+ modifiedBounds = new Rect(0, 0, bmWidth, bmHeight);
+ } else {
+ modBitmapRotate = Bitmap.createBitmap(bmHeight, bmWidth, mConfig);
+ nativeApplyFilterRotate(modBitmap, bmWidth, bmHeight, modBitmapRotate,
+ bmHeight, bmWidth, mGeometry.getRotation());
+ modifiedBounds = new Rect(0, 0, bmHeight, bmWidth);
+ }
+ modBitmap = modBitmapRotate;
+ }
+ if (straighten) {
+ Rect straightenBounds = new Rect();
+ ImageGeometry.getUntranslatedStraightenCropBounds(new RectF(modifiedBounds), sAngle)
+ .roundOut(straightenBounds);
+ Bitmap modBitmapStraighten = Bitmap.createBitmap(straightenBounds.width(),
+ straightenBounds.height(), mConfig);
+ nativeApplyFilterStraighten(modBitmap, modifiedBounds.width(), modifiedBounds.height(),
+ modBitmapStraighten,
+ straightenBounds.width(), straightenBounds.height(),
+ mGeometry.getStraightenRotation());
+ modifiedBounds = straightenBounds;
+ modBitmap = modBitmapStraighten;
+ }
+ if (crop) {
+ Bitmap modBitmapCrop = Bitmap.createBitmap(cropBounds.width(), cropBounds.height(),
+ mConfig);
+ // Force crop bounds to be within straighten bounds.
+ if (!modifiedBounds.intersect(cropBounds)) {
+ return modBitmap;
+ }
+ nativeApplyFilterCrop(modBitmap, bmWidth, bmHeight, modBitmapCrop,
+ cropBounds.width(), cropBounds.height(), cropBounds.left, cropBounds.top);
+ modBitmap = modBitmapCrop;
}
- Bitmap flipBitmap = bitmap.copy(mConfig, true);
- nativeApplyFilterFlip(bitmap, bitmap.getWidth(), bitmap.getHeight(), flipBitmap,
- flipBitmap.getWidth(), flipBitmap.getHeight(), 1);
- return flipBitmap;
+ return modBitmap;
}
}
diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
index f3d64a518..4f172285d 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/GeometryMetadata.java
@@ -53,7 +53,15 @@ public class GeometryMetadata {
public Bitmap apply(Bitmap original, float scaleFactor, boolean highQuality){
mImageFilter.setGeometryMetadata(this);
- return mImageFilter.apply(original, scaleFactor, highQuality);
+ Bitmap m = mImageFilter.apply(original, scaleFactor, highQuality);
+ mPhotoBounds.set(0,0, m.getWidth(), m.getHeight());
+ mCropBounds.set(mPhotoBounds);
+ mScaleFactor = 0;
+ mRotation = 0;
+ mStraightenRotation = 0;
+ mFlip = FLIP.NONE;
+ mSafe = false;
+ return m;
}
public GeometryMetadata(float scale, float rotation, float straighten, RectF cropBounds,
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
index c6709e81f..606e4770c 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageGeometry.java
@@ -499,6 +499,16 @@ public abstract class ImageGeometry extends ImageSlave {
}
protected RectF getStraightenCropBounds(RectF imageRect, float straightenAngle) {
+ RectF boundsRect = getUntranslatedStraightenCropBounds(imageRect, straightenAngle);
+ RectF nonRotateImage = getLocalPhotoBounds();
+ Matrix m1 = new Matrix();
+ m1.setTranslate(nonRotateImage.centerX() - boundsRect.centerX(), nonRotateImage.centerY()
+ - boundsRect.centerY());
+ m1.mapRect(boundsRect);
+ return boundsRect;
+ }
+
+ public static RectF getUntranslatedStraightenCropBounds(RectF imageRect, float straightenAngle) {
float deg = straightenAngle;
if (deg < 0) {
deg = -deg;
@@ -519,13 +529,7 @@ public abstract class ImageGeometry extends ImageSlave {
float right = (float) (left + ww);
float bottom = (float) (top + hh);
- RectF boundsRect = new RectF(left, top, right, bottom);
- RectF nonRotateImage = getLocalPhotoBounds();
- Matrix m1 = new Matrix();
- m1.setTranslate(nonRotateImage.centerX() - boundsRect.centerX(), nonRotateImage.centerY()
- - boundsRect.centerY());
- m1.mapRect(boundsRect);
- return boundsRect;
+ return new RectF(left, top, right, bottom);
}
protected void drawShadows(Canvas canvas, RectF innerBounds, RectF outerBounds, Paint p) {
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
index 2c20706a7..185ac2a3a 100644
--- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
+++ b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java
@@ -414,9 +414,8 @@ public class ImageShow extends View implements SliderListener, OnSeekBarChangeLi
float w = image.getWidth();
float h = image.getHeight();
RectF r = new RectF(0, 0, w, h);
- RectF c = new RectF(w / 4f, h / 4f, w * 3 / 4f, h * 3 / 4f);
- getImagePreset().mGeoData.setPhotoBounds(r);
- getImagePreset().mGeoData.setCropBounds(c);
+ mImagePreset.mGeoData.setPhotoBounds(r);
+ mImagePreset.mGeoData.setCropBounds(r);
setDirtyGeometryFlag();
}