diff options
author | Sascha Haeberling <haeberling@google.com> | 2013-08-06 11:43:02 -0700 |
---|---|---|
committer | Sascha Haeberling <haeberling@google.com> | 2013-08-06 11:43:02 -0700 |
commit | 8e963a5a6016d246184ed65906f9d103e92b17e2 (patch) | |
tree | 02eb244ea4a20d9aa8e43916a40b876be8935d11 /src/com/android/gallery3d/filtershow/imageshow | |
parent | 4fc90b07dcf316c7ce6c5313af8202e84bc85603 (diff) | |
download | android_packages_apps_Snap-8e963a5a6016d246184ed65906f9d103e92b17e2.tar.gz android_packages_apps_Snap-8e963a5a6016d246184ed65906f9d103e92b17e2.tar.bz2 android_packages_apps_Snap-8e963a5a6016d246184ed65906f9d103e92b17e2.zip |
This removes all non-Camera stuff from Camera2.
Note: Camera2 is a clone of Gallery2 right now.
Note 2: I will bring .mk files back later.
Change-Id: Ida958654296f5ebaacb6bb0ff59d52a7c37ce6fc
Diffstat (limited to 'src/com/android/gallery3d/filtershow/imageshow')
20 files changed, 0 insertions, 4810 deletions
diff --git a/src/com/android/gallery3d/filtershow/imageshow/ControlPoint.java b/src/com/android/gallery3d/filtershow/imageshow/ControlPoint.java deleted file mode 100644 index aaec728a6..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ControlPoint.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.imageshow; - -public class ControlPoint implements Comparable { - public float x; - public float y; - - public ControlPoint(float px, float py) { - x = px; - y = py; - } - - public ControlPoint(ControlPoint point) { - x = point.x; - y = point.y; - } - - public boolean sameValues(ControlPoint other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - - if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x)) { - return false; - } - if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y)) { - return false; - } - return true; - } - - public ControlPoint copy() { - return new ControlPoint(x, y); - } - - @Override - public int compareTo(Object another) { - ControlPoint p = (ControlPoint) another; - if (p.x < x) { - return 1; - } else if (p.x > x) { - return -1; - } - return 0; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java b/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java deleted file mode 100644 index 8ceb37599..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/EclipseControl.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.RadialGradient; -import android.graphics.RectF; -import android.graphics.Shader; - -import com.android.gallery3d.R; - -public class EclipseControl { - private float mCenterX = Float.NaN; - private float mCenterY = 0; - private float mRadiusX = 200; - private float mRadiusY = 300; - private static int MIN_TOUCH_DIST = 80;// should be a resource & in dips - - private float[] handlex = new float[9]; - private float[] handley = new float[9]; - private int mSliderColor; - private int mCenterDotSize = 40; - private float mDownX; - private float mDownY; - private float mDownCenterX; - private float mDownCenterY; - private float mDownRadiusX; - private float mDownRadiusY; - private Matrix mScrToImg; - - private boolean mShowReshapeHandles = true; - public final static int HAN_CENTER = 0; - public final static int HAN_NORTH = 7; - public final static int HAN_NE = 8; - public final static int HAN_EAST = 1; - public final static int HAN_SE = 2; - public final static int HAN_SOUTH = 3; - public final static int HAN_SW = 4; - public final static int HAN_WEST = 5; - public final static int HAN_NW = 6; - - public EclipseControl(Context context) { - mSliderColor = Color.WHITE; - } - - public void setRadius(float x, float y) { - mRadiusX = x; - mRadiusY = y; - } - - public void setCenter(float x, float y) { - mCenterX = x; - mCenterY = y; - } - - public int getCloseHandle(float x, float y) { - float min = Float.MAX_VALUE; - int handle = -1; - for (int i = 0; i < handlex.length; i++) { - float dx = handlex[i] - x; - float dy = handley[i] - y; - float dist = dx * dx + dy * dy; - if (dist < min) { - min = dist; - handle = i; - } - } - - if (min < MIN_TOUCH_DIST * MIN_TOUCH_DIST) { - return handle; - } - for (int i = 0; i < handlex.length; i++) { - float dx = handlex[i] - x; - float dy = handley[i] - y; - float dist = (float) Math.sqrt(dx * dx + dy * dy); - } - - return -1; - } - - public void setScrToImageMatrix(Matrix scrToImg) { - mScrToImg = scrToImg; - } - - public void actionDown(float x, float y, Oval oval) { - float[] point = new float[] { - x, y }; - mScrToImg.mapPoints(point); - mDownX = point[0]; - mDownY = point[1]; - mDownCenterX = oval.getCenterX(); - mDownCenterY = oval.getCenterY(); - mDownRadiusX = oval.getRadiusX(); - mDownRadiusY = oval.getRadiusY(); - } - - public void actionMove(int handle, float x, float y, Oval oval) { - float[] point = new float[] { - x, y }; - mScrToImg.mapPoints(point); - x = point[0]; - y = point[1]; - - // Test if the matrix is swapping x and y - point[0] = 0; - point[1] = 1; - mScrToImg.mapVectors(point); - boolean swapxy = (point[0] > 0.0f); - - int sign = 1; - switch (handle) { - case HAN_CENTER: - float ctrdx = mDownX - mDownCenterX; - float ctrdy = mDownY - mDownCenterY; - oval.setCenter(x - ctrdx, y - ctrdy); - // setRepresentation(mVignetteRep); - break; - case HAN_NORTH: - sign = -1; - case HAN_SOUTH: - if (swapxy) { - float raddx = mDownRadiusY - Math.abs(mDownX - mDownCenterY); - oval.setRadiusY(Math.abs(x - oval.getCenterY() + sign * raddx)); - } else { - float raddy = mDownRadiusY - Math.abs(mDownY - mDownCenterY); - oval.setRadiusY(Math.abs(y - oval.getCenterY() + sign * raddy)); - } - break; - case HAN_EAST: - sign = -1; - case HAN_WEST: - if (swapxy) { - float raddy = mDownRadiusX - Math.abs(mDownY - mDownCenterX); - oval.setRadiusX(Math.abs(y - oval.getCenterX() + sign * raddy)); - } else { - float raddx = mDownRadiusX - Math.abs(mDownX - mDownCenterX); - oval.setRadiusX(Math.abs(x - oval.getCenterX() - sign * raddx)); - } - break; - case HAN_SE: - case HAN_NE: - case HAN_SW: - case HAN_NW: - float sin45 = (float) Math.sin(45); - float dr = (mDownRadiusX + mDownRadiusY) * sin45; - float ctr_dx = mDownX - mDownCenterX; - float ctr_dy = mDownY - mDownCenterY; - float downRad = Math.abs(ctr_dx) + Math.abs(ctr_dy) - dr; - float rx = oval.getRadiusX(); - float ry = oval.getRadiusY(); - float r = (Math.abs(rx) + Math.abs(ry)) * sin45; - float dx = x - oval.getCenterX(); - float dy = y - oval.getCenterY(); - float nr = Math.abs(Math.abs(dx) + Math.abs(dy) - downRad); - oval.setRadius(rx * nr / r, ry * nr / r); - - break; - } - } - - public void paintGrayPoint(Canvas canvas, float x, float y) { - if (x == Float.NaN) { - return; - } - - Paint paint = new Paint(); - - paint.setStyle(Paint.Style.FILL); - paint.setColor(Color.BLUE); - int[] colors3 = new int[] { - Color.GRAY, Color.LTGRAY, 0x66000000, 0 }; - RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] { - 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP); - paint.setShader(g); - canvas.drawCircle(x, y, mCenterDotSize, paint); - } - - public void paintPoint(Canvas canvas, float x, float y) { - if (x == Float.NaN) { - return; - } - - Paint paint = new Paint(); - - paint.setStyle(Paint.Style.FILL); - paint.setColor(Color.BLUE); - int[] colors3 = new int[] { - mSliderColor, mSliderColor, 0x66000000, 0 }; - RadialGradient g = new RadialGradient(x, y, mCenterDotSize, colors3, new float[] { - 0, .3f, .31f, 1 }, Shader.TileMode.CLAMP); - paint.setShader(g); - canvas.drawCircle(x, y, mCenterDotSize, paint); - } - - void paintRadius(Canvas canvas, float cx, float cy, float rx, float ry) { - if (cx == Float.NaN) { - return; - } - int mSliderColor = 0xFF33B5E5; - Paint paint = new Paint(); - RectF rect = new RectF(cx - rx, cy - ry, cx + rx, cy + ry); - paint.setAntiAlias(true); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(6); - paint.setColor(Color.BLACK); - paintOvallines(canvas, rect, paint, cx, cy, rx, ry); - - paint.setStrokeWidth(3); - paint.setColor(Color.WHITE); - paintOvallines(canvas, rect, paint, cx, cy, rx, ry); - } - - public void paintOvallines( - Canvas canvas, RectF rect, Paint paint, float cx, float cy, float rx, float ry) { - canvas.drawOval(rect, paint); - float da = 4; - float arclen = da + da; - if (mShowReshapeHandles) { - paint.setStyle(Paint.Style.STROKE); - - for (int i = 0; i < 361; i += 90) { - float dx = rx + 10; - float dy = ry + 10; - rect.left = cx - dx; - rect.top = cy - dy; - rect.right = cx + dx; - rect.bottom = cy + dy; - canvas.drawArc(rect, i - da, arclen, false, paint); - dx = rx - 10; - dy = ry - 10; - rect.left = cx - dx; - rect.top = cy - dy; - rect.right = cx + dx; - rect.bottom = cy + dy; - canvas.drawArc(rect, i - da, arclen, false, paint); - } - } - da *= 2; - paint.setStyle(Paint.Style.FILL); - - for (int i = 45; i < 361; i += 90) { - double angle = Math.PI * i / 180.; - float x = cx + (float) (rx * Math.cos(angle)); - float y = cy + (float) (ry * Math.sin(angle)); - canvas.drawRect(x - da, y - da, x + da, y + da, paint); - } - paint.setStyle(Paint.Style.STROKE); - rect.left = cx - rx; - rect.top = cy - ry; - rect.right = cx + rx; - rect.bottom = cy + ry; - } - - public void fillHandles(Canvas canvas, float cx, float cy, float rx, float ry) { - handlex[0] = cx; - handley[0] = cy; - int k = 1; - - for (int i = 0; i < 360; i += 45) { - double angle = Math.PI * i / 180.; - - float x = cx + (float) (rx * Math.cos(angle)); - float y = cy + (float) (ry * Math.sin(angle)); - handlex[k] = x; - handley[k] = y; - - k++; - } - } - - public void draw(Canvas canvas) { - paintRadius(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY); - fillHandles(canvas, mCenterX, mCenterY, mRadiusX, mRadiusY); - paintPoint(canvas, mCenterX, mCenterY); - } - - public boolean isUndefined() { - return Float.isNaN(mCenterX); - } - - public void setShowReshapeHandles(boolean showReshapeHandles) { - this.mShowReshapeHandles = showReshapeHandles; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java b/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java deleted file mode 100644 index 81394f142..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/GeometryMathUtils.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * 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.imageshow; - -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.RectF; - -import com.android.gallery3d.filtershow.cache.ImageLoader; -import com.android.gallery3d.filtershow.filters.FilterCropRepresentation; -import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation; -import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation.Mirror; -import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation; -import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation.Rotation; -import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation; -import com.android.gallery3d.filtershow.pipeline.ImagePreset; - -import java.util.Collection; -import java.util.Iterator; - -public final class GeometryMathUtils { - private GeometryMathUtils() {}; - - // Holder class for Geometry data. - public static final class GeometryHolder { - public Rotation rotation = FilterRotateRepresentation.getNil(); - public float straighten = FilterStraightenRepresentation.getNil(); - public RectF crop = FilterCropRepresentation.getNil(); - public Mirror mirror = FilterMirrorRepresentation.getNil(); - - public void set(GeometryHolder h) { - rotation = h.rotation; - straighten = h.straighten; - crop.set(h.crop); - mirror = h.mirror; - } - - public void wipe() { - rotation = FilterRotateRepresentation.getNil(); - straighten = FilterStraightenRepresentation.getNil(); - crop = FilterCropRepresentation.getNil(); - mirror = FilterMirrorRepresentation.getNil(); - } - - public boolean isNil() { - return rotation == FilterRotateRepresentation.getNil() && - straighten == FilterStraightenRepresentation.getNil() && - crop.equals(FilterCropRepresentation.getNil()) && - mirror == FilterMirrorRepresentation.getNil(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof GeometryHolder)) { - return false; - } - GeometryHolder h = (GeometryHolder) o; - return rotation == h.rotation && straighten == h.straighten && - ((crop == null && h.crop == null) || (crop != null && crop.equals(h.crop))) && - mirror == h.mirror; - } - - @Override - public String toString() { - return getClass().getSimpleName() + "[" + "rotation:" + rotation.value() - + ",straighten:" + straighten + ",crop:" + crop.toString() - + ",mirror:" + mirror.value() + "]"; - } - } - - // Math operations for 2d vectors - public static float clamp(float i, float low, float high) { - return Math.max(Math.min(i, high), low); - } - - public static float[] lineIntersect(float[] line1, float[] line2) { - float a0 = line1[0]; - float a1 = line1[1]; - float b0 = line1[2]; - float b1 = line1[3]; - float c0 = line2[0]; - float c1 = line2[1]; - float d0 = line2[2]; - float d1 = line2[3]; - float t0 = a0 - b0; - float t1 = a1 - b1; - float t2 = b0 - d0; - float t3 = d1 - b1; - float t4 = c0 - d0; - float t5 = c1 - d1; - - float denom = t1 * t4 - t0 * t5; - if (denom == 0) - return null; - float u = (t3 * t4 + t5 * t2) / denom; - float[] intersect = { - b0 + u * t0, b1 + u * t1 - }; - return intersect; - } - - public static float[] shortestVectorFromPointToLine(float[] point, float[] line) { - float x1 = line[0]; - float x2 = line[2]; - float y1 = line[1]; - float y2 = line[3]; - float xdelt = x2 - x1; - float ydelt = y2 - y1; - if (xdelt == 0 && ydelt == 0) - return null; - float u = ((point[0] - x1) * xdelt + (point[1] - y1) * ydelt) - / (xdelt * xdelt + ydelt * ydelt); - float[] ret = { - (x1 + u * (x2 - x1)), (y1 + u * (y2 - y1)) - }; - float[] vec = { - ret[0] - point[0], ret[1] - point[1] - }; - return vec; - } - - // A . B - public static float dotProduct(float[] a, float[] b) { - return a[0] * b[0] + a[1] * b[1]; - } - - public static float[] normalize(float[] a) { - float length = (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]); - float[] b = { - a[0] / length, a[1] / length - }; - return b; - } - - // A onto B - public static float scalarProjection(float[] a, float[] b) { - float length = (float) Math.sqrt(b[0] * b[0] + b[1] * b[1]); - return dotProduct(a, b) / length; - } - - public static float[] getVectorFromPoints(float[] point1, float[] point2) { - float[] p = { - point2[0] - point1[0], point2[1] - point1[1] - }; - return p; - } - - public static float[] getUnitVectorFromPoints(float[] point1, float[] point2) { - float[] p = { - point2[0] - point1[0], point2[1] - point1[1] - }; - float length = (float) Math.sqrt(p[0] * p[0] + p[1] * p[1]); - p[0] = p[0] / length; - p[1] = p[1] / length; - return p; - } - - public static void scaleRect(RectF r, float scale) { - r.set(r.left * scale, r.top * scale, r.right * scale, r.bottom * scale); - } - - // A - B - public static float[] vectorSubtract(float[] a, float[] b) { - int len = a.length; - if (len != b.length) - return null; - float[] ret = new float[len]; - for (int i = 0; i < len; i++) { - ret[i] = a[i] - b[i]; - } - return ret; - } - - public static float vectorLength(float[] a) { - return (float) Math.sqrt(a[0] * a[0] + a[1] * a[1]); - } - - public static float scale(float oldWidth, float oldHeight, float newWidth, float newHeight) { - if (oldHeight == 0 || oldWidth == 0 || (oldWidth == newWidth && oldHeight == newHeight)) { - return 1; - } - return Math.min(newWidth / oldWidth, newHeight / oldHeight); - } - - public static Rect roundNearest(RectF r) { - Rect q = new Rect(Math.round(r.left), Math.round(r.top), Math.round(r.right), - Math.round(r.bottom)); - return q; - } - - private static void concatMirrorMatrix(Matrix m, Mirror type) { - if (type == Mirror.HORIZONTAL) { - m.postScale(-1, 1); - } else if (type == Mirror.VERTICAL) { - m.postScale(1, -1); - } else if (type == Mirror.BOTH) { - m.postScale(1, -1); - m.postScale(-1, 1); - } - } - - private static int getRotationForOrientation(int orientation) { - switch (orientation) { - case ImageLoader.ORI_ROTATE_90: - return 90; - case ImageLoader.ORI_ROTATE_180: - return 180; - case ImageLoader.ORI_ROTATE_270: - return 270; - default: - return 0; - } - } - - public static GeometryHolder unpackGeometry(Collection<FilterRepresentation> geometry) { - GeometryHolder holder = new GeometryHolder(); - unpackGeometry(holder, geometry); - return holder; - } - - public static void unpackGeometry(GeometryHolder out, - Collection<FilterRepresentation> geometry) { - out.wipe(); - // Get geometry data from filters - for (FilterRepresentation r : geometry) { - if (r.isNil()) { - continue; - } - if (r.getSerializationName() == FilterRotateRepresentation.SERIALIZATION_NAME) { - out.rotation = ((FilterRotateRepresentation) r).getRotation(); - } else if (r.getSerializationName() == - FilterStraightenRepresentation.SERIALIZATION_NAME) { - out.straighten = ((FilterStraightenRepresentation) r).getStraighten(); - } else if (r.getSerializationName() == FilterCropRepresentation.SERIALIZATION_NAME) { - ((FilterCropRepresentation) r).getCrop(out.crop); - } else if (r.getSerializationName() == FilterMirrorRepresentation.SERIALIZATION_NAME) { - out.mirror = ((FilterMirrorRepresentation) r).getMirror(); - } - } - } - - public static void replaceInstances(Collection<FilterRepresentation> geometry, - FilterRepresentation rep) { - Iterator<FilterRepresentation> iter = geometry.iterator(); - while (iter.hasNext()) { - FilterRepresentation r = iter.next(); - if (ImagePreset.sameSerializationName(rep, r)) { - iter.remove(); - } - } - if (!rep.isNil()) { - geometry.add(rep); - } - } - - public static void initializeHolder(GeometryHolder outHolder, - FilterRepresentation currentLocal) { - Collection<FilterRepresentation> geometry = MasterImage.getImage().getPreset() - .getGeometryFilters(); - replaceInstances(geometry, currentLocal); - unpackGeometry(outHolder, geometry); - } - - private static Bitmap applyFullGeometryMatrix(Bitmap image, GeometryHolder holder) { - int width = image.getWidth(); - int height = image.getHeight(); - RectF crop = getTrueCropRect(holder, width, height); - Rect frame = new Rect(); - crop.roundOut(frame); - Matrix m = getCropSelectionToScreenMatrix(null, holder, width, height, frame.width(), - frame.height()); - Bitmap temp = Bitmap.createBitmap(frame.width(), frame.height(), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(temp); - Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setFilterBitmap(true); - paint.setDither(true); - canvas.drawBitmap(image, m, paint); - return temp; - } - - public static Matrix getImageToScreenMatrix(Collection<FilterRepresentation> geometry, - boolean reflectRotation, Rect bmapDimens, float viewWidth, float viewHeight) { - GeometryHolder h = unpackGeometry(geometry); - return GeometryMathUtils.getOriginalToScreen(h, reflectRotation, bmapDimens.width(), - bmapDimens.height(), viewWidth, viewHeight); - } - - public static Matrix getOriginalToScreen(GeometryHolder holder, boolean rotate, - float originalWidth, - float originalHeight, float viewWidth, float viewHeight) { - int orientation = MasterImage.getImage().getZoomOrientation(); - int rotation = getRotationForOrientation(orientation); - Rotation prev = holder.rotation; - rotation = (rotation + prev.value()) % 360; - holder.rotation = Rotation.fromValue(rotation); - Matrix m = getCropSelectionToScreenMatrix(null, holder, (int) originalWidth, - (int) originalHeight, (int) viewWidth, (int) viewHeight); - holder.rotation = prev; - return m; - } - - public static Bitmap applyGeometryRepresentations(Collection<FilterRepresentation> res, - Bitmap image) { - GeometryHolder holder = unpackGeometry(res); - Bitmap bmap = image; - // If there are geometry changes, apply them to the image - if (!holder.isNil()) { - bmap = applyFullGeometryMatrix(bmap, holder); - } - return bmap; - } - - public static RectF drawTransformedCropped(GeometryHolder holder, Canvas canvas, - Bitmap photo, int viewWidth, int viewHeight) { - if (photo == null) { - return null; - } - RectF crop = new RectF(); - Matrix m = getCropSelectionToScreenMatrix(crop, holder, photo.getWidth(), photo.getHeight(), - viewWidth, viewHeight); - canvas.save(); - canvas.clipRect(crop); - Paint p = new Paint(); - p.setAntiAlias(true); - canvas.drawBitmap(photo, m, p); - canvas.restore(); - return crop; - } - - public static boolean needsDimensionSwap(Rotation rotation) { - switch (rotation) { - case NINETY: - case TWO_SEVENTY: - return true; - default: - return false; - } - } - - // Gives matrix for rotated, straightened, mirrored bitmap centered at 0,0. - private static Matrix getFullGeometryMatrix(GeometryHolder holder, int bitmapWidth, - int bitmapHeight) { - float centerX = bitmapWidth / 2f; - float centerY = bitmapHeight / 2f; - Matrix m = new Matrix(); - m.setTranslate(-centerX, -centerY); - m.postRotate(holder.straighten + holder.rotation.value()); - concatMirrorMatrix(m, holder.mirror); - return m; - } - - public static Matrix getFullGeometryToScreenMatrix(GeometryHolder holder, int bitmapWidth, - int bitmapHeight, int viewWidth, int viewHeight) { - float scale = GeometryMathUtils.scale(bitmapWidth, bitmapHeight, viewWidth, viewHeight); - Matrix m = getFullGeometryMatrix(holder, bitmapWidth, bitmapHeight); - m.postScale(scale, scale); - m.postTranslate(viewWidth / 2f, viewHeight / 2f); - return m; - } - - public static RectF getTrueCropRect(GeometryHolder holder, int bitmapWidth, int bitmapHeight) { - RectF r = new RectF(holder.crop); - FilterCropRepresentation.findScaledCrop(r, bitmapWidth, bitmapHeight); - float s = holder.straighten; - holder.straighten = 0; - Matrix m1 = getFullGeometryMatrix(holder, bitmapWidth, bitmapHeight); - holder.straighten = s; - m1.mapRect(r); - return r; - } - - public static Matrix getCropSelectionToScreenMatrix(RectF outCrop, GeometryHolder holder, - int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight) { - Matrix m = getFullGeometryMatrix(holder, bitmapWidth, bitmapHeight); - RectF crop = getTrueCropRect(holder, bitmapWidth, bitmapHeight); - float scale = GeometryMathUtils.scale(crop.width(), crop.height(), viewWidth, viewHeight); - m.postScale(scale, scale); - GeometryMathUtils.scaleRect(crop, scale); - m.postTranslate(viewWidth / 2f - crop.centerX(), viewHeight / 2f - crop.centerY()); - if (outCrop != null) { - crop.offset(viewWidth / 2f - crop.centerX(), viewHeight / 2f - crop.centerY()); - outCrop.set(crop); - } - return m; - } - - public static Matrix getCropSelectionToScreenMatrix(RectF outCrop, - Collection<FilterRepresentation> res, int bitmapWidth, int bitmapHeight, int viewWidth, - int viewHeight) { - GeometryHolder holder = unpackGeometry(res); - return getCropSelectionToScreenMatrix(outCrop, holder, bitmapWidth, bitmapHeight, - viewWidth, viewHeight); - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/GradControl.java b/src/com/android/gallery3d/filtershow/imageshow/GradControl.java deleted file mode 100644 index 964da99e9..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/GradControl.java +++ /dev/null @@ -1,274 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.DashPathEffect; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.RadialGradient; -import android.graphics.Rect; -import android.graphics.Shader; - -import com.android.gallery3d.R; - -public class GradControl { - private float mPoint1X = Float.NaN; // used to flag parameters have not been set - private float mPoint1Y = 0; - private float mPoint2X = 200; - private float mPoint2Y = 300; - private int mMinTouchDist = 80;// should be a resource & in dips - - private float[] handlex = new float[3]; - private float[] handley = new float[3]; - private int mSliderColor; - private int mCenterDotSize; - private float mDownX; - private float mDownY; - private float mDownPoint1X; - private float mDownPoint1Y; - private float mDownPoint2X; - private float mDownPoint2Y; - Rect mImageBounds; - int mImageHeight; - private Matrix mScrToImg; - Paint mPaint = new Paint(); - DashPathEffect mDash = new DashPathEffect(new float[]{30, 30}, 0); - private boolean mShowReshapeHandles = true; - public final static int HAN_CENTER = 0; - public final static int HAN_NORTH = 2; - public final static int HAN_SOUTH = 1; - private int[] mPointColorPatern; - private int[] mGrayPointColorPatern; - private float[] mPointRadialPos = new float[]{0, .3f, .31f, 1}; - private int mLineColor; - private int mlineShadowColor; - - public GradControl(Context context) { - - Resources res = context.getResources(); - mCenterDotSize = (int) res.getDimension(R.dimen.gradcontrol_dot_size); - mMinTouchDist = (int) res.getDimension(R.dimen.gradcontrol_min_touch_dist); - int grayPointCenterColor = res.getColor(R.color.gradcontrol_graypoint_center); - int grayPointEdgeColor = res.getColor(R.color.gradcontrol_graypoint_edge); - int pointCenterColor = res.getColor(R.color.gradcontrol_point_center); - int pointEdgeColor = res.getColor(R.color.gradcontrol_point_edge); - int pointShadowStartColor = res.getColor(R.color.gradcontrol_point_shadow_start); - int pointShadowEndColor = res.getColor(R.color.gradcontrol_point_shadow_end); - mPointColorPatern = new int[]{ - pointCenterColor, pointEdgeColor, pointShadowStartColor, pointShadowEndColor}; - mGrayPointColorPatern = new int[]{ - grayPointCenterColor, grayPointEdgeColor, pointShadowStartColor, pointShadowEndColor}; - mSliderColor = Color.WHITE; - mLineColor = res.getColor(R.color.gradcontrol_line_color); - mlineShadowColor = res.getColor(R.color.gradcontrol_line_shadow); - } - - public void setPoint2(float x, float y) { - mPoint2X = x; - mPoint2Y = y; - } - - public void setPoint1(float x, float y) { - mPoint1X = x; - mPoint1Y = y; - } - - public int getCloseHandle(float x, float y) { - float min = Float.MAX_VALUE; - int handle = -1; - for (int i = 0; i < handlex.length; i++) { - float dx = handlex[i] - x; - float dy = handley[i] - y; - float dist = dx * dx + dy * dy; - if (dist < min) { - min = dist; - handle = i; - } - } - - if (min < mMinTouchDist * mMinTouchDist) { - return handle; - } - for (int i = 0; i < handlex.length; i++) { - float dx = handlex[i] - x; - float dy = handley[i] - y; - float dist = (float) Math.sqrt(dx * dx + dy * dy); - } - - return -1; - } - - public void setScrImageInfo(Matrix scrToImg, Rect imageBounds) { - mScrToImg = scrToImg; - mImageBounds = new Rect(imageBounds); - } - - private boolean centerIsOutside(float x1, float y1, float x2, float y2) { - return (!mImageBounds.contains((int) ((x1 + x2) / 2), (int) ((y1 + y2) / 2))); - } - - public void actionDown(float x, float y, Line line) { - float[] point = new float[]{ - x, y}; - mScrToImg.mapPoints(point); - mDownX = point[0]; - mDownY = point[1]; - mDownPoint1X = line.getPoint1X(); - mDownPoint1Y = line.getPoint1Y(); - mDownPoint2X = line.getPoint2X(); - mDownPoint2Y = line.getPoint2Y(); - } - - public void actionMove(int handle, float x, float y, Line line) { - float[] point = new float[]{ - x, y}; - mScrToImg.mapPoints(point); - x = point[0]; - y = point[1]; - - // Test if the matrix is swapping x and y - point[0] = 0; - point[1] = 1; - mScrToImg.mapVectors(point); - boolean swapxy = (point[0] > 0.0f); - - int sign = 1; - - float dx = x - mDownX; - float dy = y - mDownY; - switch (handle) { - case HAN_CENTER: - if (centerIsOutside(mDownPoint1X + dx, mDownPoint1Y + dy, - mDownPoint2X + dx, mDownPoint2Y + dy)) { - break; - } - line.setPoint1(mDownPoint1X + dx, mDownPoint1Y + dy); - line.setPoint2(mDownPoint2X + dx, mDownPoint2Y + dy); - break; - case HAN_SOUTH: - if (centerIsOutside(mDownPoint1X + dx, mDownPoint1Y + dy, - mDownPoint2X, mDownPoint2Y)) { - break; - } - line.setPoint1(mDownPoint1X + dx, mDownPoint1Y + dy); - break; - case HAN_NORTH: - if (centerIsOutside(mDownPoint1X, mDownPoint1Y, - mDownPoint2X + dx, mDownPoint2Y + dy)) { - break; - } - line.setPoint2(mDownPoint2X + dx, mDownPoint2Y + dy); - break; - } - } - - public void paintGrayPoint(Canvas canvas, float x, float y) { - if (isUndefined()) { - return; - } - - Paint paint = new Paint(); - paint.setStyle(Paint.Style.FILL); - RadialGradient g = new RadialGradient(x, y, mCenterDotSize, mGrayPointColorPatern, - mPointRadialPos, Shader.TileMode.CLAMP); - paint.setShader(g); - canvas.drawCircle(x, y, mCenterDotSize, paint); - } - - public void paintPoint(Canvas canvas, float x, float y) { - if (isUndefined()) { - return; - } - - Paint paint = new Paint(); - paint.setStyle(Paint.Style.FILL); - RadialGradient g = new RadialGradient(x, y, mCenterDotSize, mPointColorPatern, - mPointRadialPos, Shader.TileMode.CLAMP); - paint.setShader(g); - canvas.drawCircle(x, y, mCenterDotSize, paint); - } - - void paintLines(Canvas canvas, float p1x, float p1y, float p2x, float p2y) { - if (isUndefined()) { - return; - } - - mPaint.setAntiAlias(true); - mPaint.setStyle(Paint.Style.STROKE); - - mPaint.setStrokeWidth(6); - mPaint.setColor(mlineShadowColor); - mPaint.setPathEffect(mDash); - paintOvallines(canvas, mPaint, p1x, p1y, p2x, p2y); - - mPaint.setStrokeWidth(3); - mPaint.setColor(mLineColor); - mPaint.setPathEffect(mDash); - paintOvallines(canvas, mPaint, p1x, p1y, p2x, p2y); - } - - public void paintOvallines( - Canvas canvas, Paint paint, float p1x, float p1y, float p2x, float p2y) { - - - - canvas.drawLine(p1x, p1y, p2x, p2y, paint); - - float cx = (p1x + p2x) / 2; - float cy = (p1y + p2y) / 2; - float dx = p1x - p2x; - float dy = p1y - p2y; - float len = (float) Math.sqrt(dx * dx + dy * dy); - dx *= 2048 / len; - dy *= 2048 / len; - - canvas.drawLine(p1x + dy, p1y - dx, p1x - dy, p1y + dx, paint); - canvas.drawLine(p2x + dy, p2y - dx, p2x - dy, p2y + dx, paint); - } - - public void fillHandles(Canvas canvas, float p1x, float p1y, float p2x, float p2y) { - float cx = (p1x + p2x) / 2; - float cy = (p1y + p2y) / 2; - handlex[0] = cx; - handley[0] = cy; - handlex[1] = p1x; - handley[1] = p1y; - handlex[2] = p2x; - handley[2] = p2y; - - } - - public void draw(Canvas canvas) { - paintLines(canvas, mPoint1X, mPoint1Y, mPoint2X, mPoint2Y); - fillHandles(canvas, mPoint1X, mPoint1Y, mPoint2X, mPoint2Y); - paintPoint(canvas, mPoint2X, mPoint2Y); - paintPoint(canvas, mPoint1X, mPoint1Y); - paintPoint(canvas, (mPoint1X + mPoint2X) / 2, (mPoint1Y + mPoint2Y) / 2); - } - - public boolean isUndefined() { - return Float.isNaN(mPoint1X); - } - - public void setShowReshapeHandles(boolean showReshapeHandles) { - this.mShowReshapeHandles = showReshapeHandles; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java b/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java deleted file mode 100644 index 7fee03188..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageCrop.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2013 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.imageshow; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.util.Log; -import android.view.MotionEvent; - -import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.crop.CropDrawingUtils; -import com.android.gallery3d.filtershow.crop.CropMath; -import com.android.gallery3d.filtershow.crop.CropObject; -import com.android.gallery3d.filtershow.editors.EditorCrop; -import com.android.gallery3d.filtershow.filters.FilterCropRepresentation; -import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; - -public class ImageCrop extends ImageShow { - private static final String TAG = ImageCrop.class.getSimpleName(); - private RectF mImageBounds = new RectF(); - private RectF mScreenCropBounds = new RectF(); - private Paint mPaint = new Paint(); - private CropObject mCropObj = null; - private GeometryHolder mGeometry = new GeometryHolder(); - private GeometryHolder mUpdateHolder = new GeometryHolder(); - private Drawable mCropIndicator; - private int mIndicatorSize; - private boolean mMovingBlock = false; - private Matrix mDisplayMatrix = null; - private Matrix mDisplayCropMatrix = null; - private Matrix mDisplayMatrixInverse = null; - private float mPrevX = 0; - private float mPrevY = 0; - private int mMinSideSize = 90; - private int mTouchTolerance = 40; - private enum Mode { - NONE, MOVE - } - private Mode mState = Mode.NONE; - private boolean mValidDraw = false; - FilterCropRepresentation mLocalRep = new FilterCropRepresentation(); - EditorCrop mEditorCrop; - - public ImageCrop(Context context) { - super(context); - setup(context); - } - - public ImageCrop(Context context, AttributeSet attrs) { - super(context, attrs); - setup(context); - } - - public ImageCrop(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setup(context); - } - - private void setup(Context context) { - Resources rsc = context.getResources(); - mCropIndicator = rsc.getDrawable(R.drawable.camera_crop); - mIndicatorSize = (int) rsc.getDimension(R.dimen.crop_indicator_size); - mMinSideSize = (int) rsc.getDimension(R.dimen.crop_min_side); - mTouchTolerance = (int) rsc.getDimension(R.dimen.crop_touch_tolerance); - } - - public void setFilterCropRepresentation(FilterCropRepresentation crop) { - mLocalRep = (crop == null) ? new FilterCropRepresentation() : crop; - GeometryMathUtils.initializeHolder(mUpdateHolder, mLocalRep); - mValidDraw = true; - } - - public FilterCropRepresentation getFinalRepresentation() { - return mLocalRep; - } - - private void internallyUpdateLocalRep(RectF crop, RectF image) { - FilterCropRepresentation - .findNormalizedCrop(crop, (int) image.width(), (int) image.height()); - mGeometry.crop.set(crop); - mUpdateHolder.set(mGeometry); - mLocalRep.setCrop(crop); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - if (mDisplayMatrix == null || mDisplayMatrixInverse == null) { - return true; - } - float[] touchPoint = { - x, y - }; - mDisplayMatrixInverse.mapPoints(touchPoint); - x = touchPoint[0]; - y = touchPoint[1]; - switch (event.getActionMasked()) { - case (MotionEvent.ACTION_DOWN): - if (mState == Mode.NONE) { - if (!mCropObj.selectEdge(x, y)) { - mMovingBlock = mCropObj.selectEdge(CropObject.MOVE_BLOCK); - } - mPrevX = x; - mPrevY = y; - mState = Mode.MOVE; - } - break; - case (MotionEvent.ACTION_UP): - if (mState == Mode.MOVE) { - mCropObj.selectEdge(CropObject.MOVE_NONE); - mMovingBlock = false; - mPrevX = x; - mPrevY = y; - mState = Mode.NONE; - internallyUpdateLocalRep(mCropObj.getInnerBounds(), mCropObj.getOuterBounds()); - } - break; - case (MotionEvent.ACTION_MOVE): - if (mState == Mode.MOVE) { - float dx = x - mPrevX; - float dy = y - mPrevY; - mCropObj.moveCurrentSelection(dx, dy); - mPrevX = x; - mPrevY = y; - } - break; - default: - break; - } - invalidate(); - return true; - } - - private void clearDisplay() { - mDisplayMatrix = null; - mDisplayMatrixInverse = null; - invalidate(); - } - - public void applyFreeAspect() { - mCropObj.unsetAspectRatio(); - invalidate(); - } - - public void applyOriginalAspect() { - RectF outer = mCropObj.getOuterBounds(); - float w = outer.width(); - float h = outer.height(); - if (w > 0 && h > 0) { - applyAspect(w, h); - mCropObj.resetBoundsTo(outer, outer); - internallyUpdateLocalRep(mCropObj.getInnerBounds(), mCropObj.getOuterBounds()); - } else { - Log.w(TAG, "failed to set aspect ratio original"); - } - invalidate(); - } - - public void applyAspect(float x, float y) { - if (x <= 0 || y <= 0) { - throw new IllegalArgumentException("Bad arguments to applyAspect"); - } - // If we are rotated by 90 degrees from horizontal, swap x and y - if (GeometryMathUtils.needsDimensionSwap(mGeometry.rotation)) { - float tmp = x; - x = y; - y = tmp; - } - if (!mCropObj.setInnerAspectRatio(x, y)) { - Log.w(TAG, "failed to set aspect ratio"); - } - internallyUpdateLocalRep(mCropObj.getInnerBounds(), mCropObj.getOuterBounds()); - invalidate(); - } - - /** - * Rotates first d bits in integer x to the left some number of times. - */ - private int bitCycleLeft(int x, int times, int d) { - int mask = (1 << d) - 1; - int mout = x & mask; - times %= d; - int hi = mout >> (d - times); - int low = (mout << times) & mask; - int ret = x & ~mask; - ret |= low; - ret |= hi; - return ret; - } - - /** - * Find the selected edge or corner in screen coordinates. - */ - private int decode(int movingEdges, float rotation) { - int rot = CropMath.constrainedRotation(rotation); - switch (rot) { - case 90: - return bitCycleLeft(movingEdges, 1, 4); - case 180: - return bitCycleLeft(movingEdges, 2, 4); - case 270: - return bitCycleLeft(movingEdges, 3, 4); - default: - return movingEdges; - } - } - - private void forceStateConsistency() { - MasterImage master = MasterImage.getImage(); - Bitmap image = master.getFiltersOnlyImage(); - int width = image.getWidth(); - int height = image.getHeight(); - if (mCropObj == null || !mUpdateHolder.equals(mGeometry) - || mImageBounds.width() != width || mImageBounds.height() != height - || !mLocalRep.getCrop().equals(mUpdateHolder.crop)) { - mImageBounds.set(0, 0, width, height); - mGeometry.set(mUpdateHolder); - mLocalRep.setCrop(mUpdateHolder.crop); - RectF scaledCrop = new RectF(mUpdateHolder.crop); - FilterCropRepresentation.findScaledCrop(scaledCrop, width, height); - mCropObj = new CropObject(mImageBounds, scaledCrop, (int) mUpdateHolder.straighten); - mState = Mode.NONE; - clearDisplay(); - } - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - clearDisplay(); - } - - @Override - public void onDraw(Canvas canvas) { - Bitmap bitmap = MasterImage.getImage().getFiltersOnlyImage(); - if (!mValidDraw || bitmap == null) { - return; - } - forceStateConsistency(); - mImageBounds.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); - // If display matrix doesn't exist, create it and its dependencies - if (mDisplayCropMatrix == null || mDisplayMatrix == null || mDisplayMatrixInverse == null) { - mDisplayMatrix = GeometryMathUtils.getFullGeometryToScreenMatrix(mGeometry, - bitmap.getWidth(), bitmap.getHeight(), canvas.getWidth(), canvas.getHeight()); - float straighten = mGeometry.straighten; - mGeometry.straighten = 0; - mDisplayCropMatrix = GeometryMathUtils.getFullGeometryToScreenMatrix(mGeometry, - bitmap.getWidth(), bitmap.getHeight(), canvas.getWidth(), canvas.getHeight()); - mGeometry.straighten = straighten; - mDisplayMatrixInverse = new Matrix(); - mDisplayMatrixInverse.reset(); - if (!mDisplayCropMatrix.invert(mDisplayMatrixInverse)) { - Log.w(TAG, "could not invert display matrix"); - mDisplayMatrixInverse = null; - return; - } - // Scale min side and tolerance by display matrix scale factor - mCropObj.setMinInnerSideSize(mDisplayMatrixInverse.mapRadius(mMinSideSize)); - mCropObj.setTouchTolerance(mDisplayMatrixInverse.mapRadius(mTouchTolerance)); - } - // Draw actual bitmap - mPaint.reset(); - mPaint.setAntiAlias(true); - mPaint.setFilterBitmap(true); - canvas.drawBitmap(bitmap, mDisplayMatrix, mPaint); - mCropObj.getInnerBounds(mScreenCropBounds); - RectF outer = mCropObj.getOuterBounds(); - FilterCropRepresentation.findNormalizedCrop(mScreenCropBounds, (int) outer.width(), - (int) outer.height()); - FilterCropRepresentation.findScaledCrop(mScreenCropBounds, bitmap.getWidth(), - bitmap.getHeight()); - if (mDisplayCropMatrix.mapRect(mScreenCropBounds)) { - // Draw crop rect and markers - CropDrawingUtils.drawCropRect(canvas, mScreenCropBounds); - CropDrawingUtils.drawRuleOfThird(canvas, mScreenCropBounds); - CropDrawingUtils.drawIndicators(canvas, mCropIndicator, mIndicatorSize, - mScreenCropBounds, mCropObj.isFixedAspect(), - decode(mCropObj.getSelectState(), mGeometry.rotation.value())); - } - } - - public void setEditor(EditorCrop editorCrop) { - mEditorCrop = editorCrop; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageCurves.java b/src/com/android/gallery3d/filtershow/imageshow/ImageCurves.java deleted file mode 100644 index 82c4b2fc7..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageCurves.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PorterDuff; -import android.graphics.PorterDuffXfermode; -import android.os.AsyncTask; -import android.util.AttributeSet; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.PopupMenu; - -import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.editors.Editor; -import com.android.gallery3d.filtershow.editors.EditorCurves; -import com.android.gallery3d.filtershow.filters.FilterCurvesRepresentation; -import com.android.gallery3d.filtershow.filters.FiltersManager; -import com.android.gallery3d.filtershow.filters.ImageFilterCurves; -import com.android.gallery3d.filtershow.pipeline.ImagePreset; - -import java.util.HashMap; - -public class ImageCurves extends ImageShow { - - private static final String LOGTAG = "ImageCurves"; - Paint gPaint = new Paint(); - Path gPathSpline = new Path(); - HashMap<Integer, String> mIdStrLut; - - private int mCurrentCurveIndex = Spline.RGB; - private boolean mDidAddPoint = false; - private boolean mDidDelete = false; - private ControlPoint mCurrentControlPoint = null; - private int mCurrentPick = -1; - private ImagePreset mLastPreset = null; - int[] redHistogram = new int[256]; - int[] greenHistogram = new int[256]; - int[] blueHistogram = new int[256]; - Path gHistoPath = new Path(); - - boolean mDoingTouchMove = false; - private EditorCurves mEditorCurves; - private FilterCurvesRepresentation mFilterCurvesRepresentation; - - public ImageCurves(Context context) { - super(context); - setLayerType(LAYER_TYPE_SOFTWARE, gPaint); - resetCurve(); - } - - public ImageCurves(Context context, AttributeSet attrs) { - super(context, attrs); - setLayerType(LAYER_TYPE_SOFTWARE, gPaint); - resetCurve(); - } - - @Override - protected boolean enableComparison() { - return false; - } - - @Override - public boolean useUtilityPanel() { - return true; - } - - private void showPopupMenu(LinearLayout accessoryViewList) { - final Button button = (Button) accessoryViewList.findViewById( - R.id.applyEffect); - if (button == null) { - return; - } - if (mIdStrLut == null){ - mIdStrLut = new HashMap<Integer, String>(); - mIdStrLut.put(R.id.curve_menu_rgb, - getContext().getString(R.string.curves_channel_rgb)); - mIdStrLut.put(R.id.curve_menu_red, - getContext().getString(R.string.curves_channel_red)); - mIdStrLut.put(R.id.curve_menu_green, - getContext().getString(R.string.curves_channel_green)); - mIdStrLut.put(R.id.curve_menu_blue, - getContext().getString(R.string.curves_channel_blue)); - } - PopupMenu popupMenu = new PopupMenu(getActivity(), button); - popupMenu.getMenuInflater().inflate(R.menu.filtershow_menu_curves, popupMenu.getMenu()); - popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - setChannel(item.getItemId()); - button.setText(mIdStrLut.get(item.getItemId())); - return true; - } - }); - Editor.hackFixStrings(popupMenu.getMenu()); - popupMenu.show(); - } - - @Override - public void openUtilityPanel(final LinearLayout accessoryViewList) { - Context context = accessoryViewList.getContext(); - Button view = (Button) accessoryViewList.findViewById(R.id.applyEffect); - view.setText(context.getString(R.string.curves_channel_rgb)); - view.setVisibility(View.VISIBLE); - - view.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View arg0) { - showPopupMenu(accessoryViewList); - } - }); - - if (view != null) { - view.setVisibility(View.VISIBLE); - } - } - - public void nextChannel() { - mCurrentCurveIndex = ((mCurrentCurveIndex + 1) % 4); - invalidate(); - } - - private ImageFilterCurves curves() { - String filterName = getFilterName(); - ImagePreset p = getImagePreset(); - if (p != null) { - return (ImageFilterCurves) FiltersManager.getManager().getFilter(ImageFilterCurves.class); - } - return null; - } - - private Spline getSpline(int index) { - return mFilterCurvesRepresentation.getSpline(index); - } - - @Override - public void resetParameter() { - super.resetParameter(); - resetCurve(); - mLastPreset = null; - invalidate(); - } - - public void resetCurve() { - if (mFilterCurvesRepresentation != null) { - mFilterCurvesRepresentation.reset(); - updateCachedImage(); - } - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (mFilterCurvesRepresentation == null) { - return; - } - - gPaint.setAntiAlias(true); - - if (getImagePreset() != mLastPreset && getFilteredImage() != null) { - new ComputeHistogramTask().execute(getFilteredImage()); - mLastPreset = getImagePreset(); - } - - if (curves() == null) { - return; - } - - if (mCurrentCurveIndex == Spline.RGB || mCurrentCurveIndex == Spline.RED) { - drawHistogram(canvas, redHistogram, Color.RED, PorterDuff.Mode.SCREEN); - } - if (mCurrentCurveIndex == Spline.RGB || mCurrentCurveIndex == Spline.GREEN) { - drawHistogram(canvas, greenHistogram, Color.GREEN, PorterDuff.Mode.SCREEN); - } - if (mCurrentCurveIndex == Spline.RGB || mCurrentCurveIndex == Spline.BLUE) { - drawHistogram(canvas, blueHistogram, Color.BLUE, PorterDuff.Mode.SCREEN); - } - // We only display the other channels curves when showing the RGB curve - if (mCurrentCurveIndex == Spline.RGB) { - for (int i = 0; i < 4; i++) { - Spline spline = getSpline(i); - if (i != mCurrentCurveIndex && !spline.isOriginal()) { - // And we only display a curve if it has more than two - // points - spline.draw(canvas, Spline.colorForCurve(i), getWidth(), - getHeight(), false, mDoingTouchMove); - } - } - } - // ...but we always display the current curve. - getSpline(mCurrentCurveIndex) - .draw(canvas, Spline.colorForCurve(mCurrentCurveIndex), getWidth(), getHeight(), - true, mDoingTouchMove); - - } - - private int pickControlPoint(float x, float y) { - int pick = 0; - Spline spline = getSpline(mCurrentCurveIndex); - float px = spline.getPoint(0).x; - float py = spline.getPoint(0).y; - double delta = Math.sqrt((px - x) * (px - x) + (py - y) * (py - y)); - for (int i = 1; i < spline.getNbPoints(); i++) { - px = spline.getPoint(i).x; - py = spline.getPoint(i).y; - double currentDelta = Math.sqrt((px - x) * (px - x) + (py - y) - * (py - y)); - if (currentDelta < delta) { - delta = currentDelta; - pick = i; - } - } - - if (!mDidAddPoint && (delta * getWidth() > 100) - && (spline.getNbPoints() < 10)) { - return -1; - } - - return pick; - } - - private String getFilterName() { - return "Curves"; - } - - @Override - public synchronized boolean onTouchEvent(MotionEvent e) { - if (e.getPointerCount() != 1) { - return true; - } - - if (didFinishScalingOperation()) { - return true; - } - - float margin = Spline.curveHandleSize() / 2; - float posX = e.getX(); - if (posX < margin) { - posX = margin; - } - float posY = e.getY(); - if (posY < margin) { - posY = margin; - } - if (posX > getWidth() - margin) { - posX = getWidth() - margin; - } - if (posY > getHeight() - margin) { - posY = getHeight() - margin; - } - posX = (posX - margin) / (getWidth() - 2 * margin); - posY = (posY - margin) / (getHeight() - 2 * margin); - - if (e.getActionMasked() == MotionEvent.ACTION_UP) { - mCurrentControlPoint = null; - mCurrentPick = -1; - updateCachedImage(); - mDidAddPoint = false; - if (mDidDelete) { - mDidDelete = false; - } - mDoingTouchMove = false; - return true; - } - - if (mDidDelete) { - return true; - } - - if (curves() == null) { - return true; - } - - if (e.getActionMasked() == MotionEvent.ACTION_MOVE) { - mDoingTouchMove = true; - Spline spline = getSpline(mCurrentCurveIndex); - int pick = mCurrentPick; - if (mCurrentControlPoint == null) { - pick = pickControlPoint(posX, posY); - if (pick == -1) { - mCurrentControlPoint = new ControlPoint(posX, posY); - pick = spline.addPoint(mCurrentControlPoint); - mDidAddPoint = true; - } else { - mCurrentControlPoint = spline.getPoint(pick); - } - mCurrentPick = pick; - } - - if (spline.isPointContained(posX, pick)) { - spline.movePoint(pick, posX, posY); - } else if (pick != -1 && spline.getNbPoints() > 2) { - spline.deletePoint(pick); - mDidDelete = true; - } - updateCachedImage(); - invalidate(); - } - return true; - } - - public synchronized void updateCachedImage() { - if (getImagePreset() != null) { - resetImageCaches(this); - if (mEditorCurves != null) { - mEditorCurves.commitLocalRepresentation(); - } - invalidate(); - } - } - - class ComputeHistogramTask extends AsyncTask<Bitmap, Void, int[]> { - @Override - protected int[] doInBackground(Bitmap... params) { - int[] histo = new int[256 * 3]; - Bitmap bitmap = params[0]; - int w = bitmap.getWidth(); - int h = bitmap.getHeight(); - int[] pixels = new int[w * h]; - bitmap.getPixels(pixels, 0, w, 0, 0, w, h); - for (int i = 0; i < w; i++) { - for (int j = 0; j < h; j++) { - int index = j * w + i; - int r = Color.red(pixels[index]); - int g = Color.green(pixels[index]); - int b = Color.blue(pixels[index]); - histo[r]++; - histo[256 + g]++; - histo[512 + b]++; - } - } - return histo; - } - - @Override - protected void onPostExecute(int[] result) { - System.arraycopy(result, 0, redHistogram, 0, 256); - System.arraycopy(result, 256, greenHistogram, 0, 256); - System.arraycopy(result, 512, blueHistogram, 0, 256); - invalidate(); - } - } - - private void drawHistogram(Canvas canvas, int[] histogram, int color, PorterDuff.Mode mode) { - int max = 0; - for (int i = 0; i < histogram.length; i++) { - if (histogram[i] > max) { - max = histogram[i]; - } - } - float w = getWidth() - Spline.curveHandleSize(); - float h = getHeight() - Spline.curveHandleSize() / 2.0f; - float dx = Spline.curveHandleSize() / 2.0f; - float wl = w / histogram.length; - float wh = (0.3f * h) / max; - Paint paint = new Paint(); - paint.setARGB(100, 255, 255, 255); - paint.setStrokeWidth((int) Math.ceil(wl)); - - Paint paint2 = new Paint(); - paint2.setColor(color); - paint2.setStrokeWidth(6); - paint2.setXfermode(new PorterDuffXfermode(mode)); - gHistoPath.reset(); - gHistoPath.moveTo(dx, h); - boolean firstPointEncountered = false; - float prev = 0; - float last = 0; - for (int i = 0; i < histogram.length; i++) { - float x = i * wl + dx; - float l = histogram[i] * wh; - if (l != 0) { - float v = h - (l + prev) / 2.0f; - if (!firstPointEncountered) { - gHistoPath.lineTo(x, h); - firstPointEncountered = true; - } - gHistoPath.lineTo(x, v); - prev = l; - last = x; - } - } - gHistoPath.lineTo(last, h); - gHistoPath.lineTo(w, h); - gHistoPath.close(); - canvas.drawPath(gHistoPath, paint2); - paint2.setStrokeWidth(2); - paint2.setStyle(Paint.Style.STROKE); - paint2.setARGB(255, 200, 200, 200); - canvas.drawPath(gHistoPath, paint2); - } - - public void setChannel(int itemId) { - switch (itemId) { - case R.id.curve_menu_rgb: { - mCurrentCurveIndex = Spline.RGB; - break; - } - case R.id.curve_menu_red: { - mCurrentCurveIndex = Spline.RED; - break; - } - case R.id.curve_menu_green: { - mCurrentCurveIndex = Spline.GREEN; - break; - } - case R.id.curve_menu_blue: { - mCurrentCurveIndex = Spline.BLUE; - break; - } - } - mEditorCurves.commitLocalRepresentation(); - invalidate(); - } - - public void setEditor(EditorCurves editorCurves) { - mEditorCurves = editorCurves; - } - - public void setFilterDrawRepresentation(FilterCurvesRepresentation drawRep) { - mFilterCurvesRepresentation = drawRep; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java b/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java deleted file mode 100644 index 9722034e0..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageDraw.java +++ /dev/null @@ -1,139 +0,0 @@ - -package com.android.gallery3d.filtershow.imageshow; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import com.android.gallery3d.filtershow.editors.EditorDraw; -import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation; -import com.android.gallery3d.filtershow.filters.ImageFilterDraw; - -public class ImageDraw extends ImageShow { - - private static final String LOGTAG = "ImageDraw"; - private int mCurrentColor = Color.RED; - final static float INITAL_STROKE_RADIUS = 40; - private float mCurrentSize = INITAL_STROKE_RADIUS; - private byte mType = 0; - private FilterDrawRepresentation mFRep; - private EditorDraw mEditorDraw; - - public ImageDraw(Context context, AttributeSet attrs) { - super(context, attrs); - resetParameter(); - } - - public ImageDraw(Context context) { - super(context); - resetParameter(); - } - - public void setEditor(EditorDraw editorDraw) { - mEditorDraw = editorDraw; - } - public void setFilterDrawRepresentation(FilterDrawRepresentation fr) { - mFRep = fr; - } - - public Drawable getIcon(Context context) { - - return null; - } - - @Override - public void resetParameter() { - if (mFRep != null) { - mFRep.clear(); - } - } - - public void setColor(int color) { - mCurrentColor = color; - } - - public void setSize(int size) { - mCurrentSize = size; - } - - public void setStyle(byte style) { - mType = (byte) (style % ImageFilterDraw.NUMBER_OF_STYLES); - } - - public int getStyle() { - return mType; - } - - public int getSize() { - return (int) mCurrentSize; - } - - float[] mTmpPoint = new float[2]; // so we do not malloc - @Override - public boolean onTouchEvent(MotionEvent event) { - if (event.getPointerCount() > 1) { - boolean ret = super.onTouchEvent(event); - if (mFRep.getCurrentDrawing() != null) { - mFRep.clearCurrentSection(); - mEditorDraw.commitLocalRepresentation(); - } - return ret; - } - if (event.getAction() != MotionEvent.ACTION_DOWN) { - if (mFRep.getCurrentDrawing() == null) { - return super.onTouchEvent(event); - } - } - - if (event.getAction() == MotionEvent.ACTION_DOWN) { - calcScreenMapping(); - mTmpPoint[0] = event.getX(); - mTmpPoint[1] = event.getY(); - mToOrig.mapPoints(mTmpPoint); - mFRep.startNewSection(mType, mCurrentColor, mCurrentSize, mTmpPoint[0], mTmpPoint[1]); - } - - if (event.getAction() == MotionEvent.ACTION_MOVE) { - - int historySize = event.getHistorySize(); - for (int h = 0; h < historySize; h++) { - int p = 0; - { - mTmpPoint[0] = event.getHistoricalX(p, h); - mTmpPoint[1] = event.getHistoricalY(p, h); - mToOrig.mapPoints(mTmpPoint); - mFRep.addPoint(mTmpPoint[0], mTmpPoint[1]); - } - } - } - - if (event.getAction() == MotionEvent.ACTION_UP) { - mTmpPoint[0] = event.getX(); - mTmpPoint[1] = event.getY(); - mToOrig.mapPoints(mTmpPoint); - mFRep.endSection(mTmpPoint[0], mTmpPoint[1]); - } - mEditorDraw.commitLocalRepresentation(); - invalidate(); - return true; - } - - Matrix mRotateToScreen = new Matrix(); - Matrix mToOrig; - private void calcScreenMapping() { - mToOrig = getScreenToImageMatrix(true); - mToOrig.invert(mRotateToScreen); - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - calcScreenMapping(); - - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageGrad.java b/src/com/android/gallery3d/filtershow/imageshow/ImageGrad.java deleted file mode 100644 index b55cc2bc4..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageGrad.java +++ /dev/null @@ -1,215 +0,0 @@ -package com.android.gallery3d.filtershow.imageshow; -/* - * Copyright (C) 2013 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. - */ - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.editors.EditorGrad; -import com.android.gallery3d.filtershow.filters.FilterGradRepresentation; - -public class ImageGrad extends ImageShow { - private static final String LOGTAG = "ImageGrad"; - private FilterGradRepresentation mGradRep; - private EditorGrad mEditorGrad; - private float mMinTouchDist; - private int mActiveHandle = -1; - private GradControl mEllipse; - - Matrix mToScr = new Matrix(); - float[] mPointsX = new float[FilterGradRepresentation.MAX_POINTS]; - float[] mPointsY = new float[FilterGradRepresentation.MAX_POINTS]; - - public ImageGrad(Context context) { - super(context); - Resources res = context.getResources(); - mMinTouchDist = res.getDimensionPixelSize(R.dimen.gradcontrol_min_touch_dist); - mEllipse = new GradControl(context); - mEllipse.setShowReshapeHandles(false); - } - - public ImageGrad(Context context, AttributeSet attrs) { - super(context, attrs); - Resources res = context.getResources(); - mMinTouchDist = res.getDimensionPixelSize(R.dimen.gradcontrol_min_touch_dist); - mEllipse = new GradControl(context); - mEllipse.setShowReshapeHandles(false); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - int mask = event.getActionMasked(); - - if (mActiveHandle == -1) { - if (MotionEvent.ACTION_DOWN != mask) { - return super.onTouchEvent(event); - } - if (event.getPointerCount() == 1) { - mActiveHandle = mEllipse.getCloseHandle(event.getX(), event.getY()); - if (mActiveHandle == -1) { - float x = event.getX(); - float y = event.getY(); - float min_d = Float.MAX_VALUE; - int pos = -1; - for (int i = 0; i < mPointsX.length; i++) { - if (mPointsX[i] == -1) { - continue; - } - float d = (float) Math.hypot(x - mPointsX[i], y - mPointsY[i]); - if ( min_d > d) { - min_d = d; - pos = i; - } - } - if (min_d > mMinTouchDist){ - pos = -1; - } - - if (pos != -1) { - mGradRep.setSelectedPoint(pos); - resetImageCaches(this); - mEditorGrad.updateSeekBar(mGradRep); - mEditorGrad.commitLocalRepresentation(); - invalidate(); - } - } - } - if (mActiveHandle == -1) { - return super.onTouchEvent(event); - } - } else { - switch (mask) { - case MotionEvent.ACTION_UP: { - - mActiveHandle = -1; - break; - } - case MotionEvent.ACTION_DOWN: { - break; - } - } - } - float x = event.getX(); - float y = event.getY(); - - mEllipse.setScrImageInfo(getScreenToImageMatrix(true), - MasterImage.getImage().getOriginalBounds()); - - switch (mask) { - case (MotionEvent.ACTION_DOWN): { - mEllipse.actionDown(x, y, mGradRep); - break; - } - case (MotionEvent.ACTION_UP): - case (MotionEvent.ACTION_MOVE): { - mEllipse.actionMove(mActiveHandle, x, y, mGradRep); - setRepresentation(mGradRep); - break; - } - } - invalidate(); - mEditorGrad.commitLocalRepresentation(); - return true; - } - - public void setRepresentation(FilterGradRepresentation pointRep) { - mGradRep = pointRep; - Matrix toImg = getScreenToImageMatrix(false); - - toImg.invert(mToScr); - - float[] c1 = new float[] { mGradRep.getPoint1X(), mGradRep.getPoint1Y() }; - float[] c2 = new float[] { mGradRep.getPoint2X(), mGradRep.getPoint2Y() }; - - if (c1[0] == -1) { - float cx = MasterImage.getImage().getOriginalBounds().width() / 2; - float cy = MasterImage.getImage().getOriginalBounds().height() / 2; - float rx = Math.min(cx, cy) * .4f; - - mGradRep.setPoint1(cx, cy-rx); - mGradRep.setPoint2(cx, cy+rx); - c1[0] = cx; - c1[1] = cy-rx; - mToScr.mapPoints(c1); - if (getWidth() != 0) { - mEllipse.setPoint1(c1[0], c1[1]); - c2[0] = cx; - c2[1] = cy+rx; - mToScr.mapPoints(c2); - mEllipse.setPoint2(c2[0], c2[1]); - } - mEditorGrad.commitLocalRepresentation(); - } else { - mToScr.mapPoints(c1); - mToScr.mapPoints(c2); - mEllipse.setPoint1(c1[0], c1[1]); - mEllipse.setPoint2(c2[0], c2[1]); - } - } - - public void drawOtherPoints(Canvas canvas) { - computCenterLocations(); - for (int i = 0; i < mPointsX.length; i++) { - if (mPointsX[i] != -1) { - mEllipse.paintGrayPoint(canvas, mPointsX[i], mPointsY[i]); - } - } - } - - public void computCenterLocations() { - int x1[] = mGradRep.getXPos1(); - int y1[] = mGradRep.getYPos1(); - int x2[] = mGradRep.getXPos2(); - int y2[] = mGradRep.getYPos2(); - int selected = mGradRep.getSelectedPoint(); - boolean m[] = mGradRep.getMask(); - float[] c = new float[2]; - for (int i = 0; i < m.length; i++) { - if (selected == i || !m[i]) { - mPointsX[i] = -1; - continue; - } - - c[0] = (x1[i]+x2[i])/2; - c[1] = (y1[i]+y2[i])/2; - mToScr.mapPoints(c); - - mPointsX[i] = c[0]; - mPointsY[i] = c[1]; - } - } - - public void setEditor(EditorGrad editorGrad) { - mEditorGrad = editorGrad; - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (mGradRep == null) { - return; - } - setRepresentation(mGradRep); - mEllipse.draw(canvas); - drawOtherPoints(canvas); - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageMirror.java b/src/com/android/gallery3d/filtershow/imageshow/ImageMirror.java deleted file mode 100644 index 26c49b1a8..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageMirror.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2013 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.imageshow; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import com.android.gallery3d.filtershow.editors.EditorMirror; -import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation; -import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; - -public class ImageMirror extends ImageShow { - private static final String TAG = ImageMirror.class.getSimpleName(); - private EditorMirror mEditorMirror; - private FilterMirrorRepresentation mLocalRep = new FilterMirrorRepresentation(); - private GeometryHolder mDrawHolder = new GeometryHolder(); - - public ImageMirror(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ImageMirror(Context context) { - super(context); - } - - public void setFilterMirrorRepresentation(FilterMirrorRepresentation rep) { - mLocalRep = (rep == null) ? new FilterMirrorRepresentation() : rep; - } - - public void flip() { - mLocalRep.cycle(); - invalidate(); - } - - public FilterMirrorRepresentation getFinalRepresentation() { - return mLocalRep; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // Treat event as handled. - return true; - } - - @Override - public void onDraw(Canvas canvas) { - MasterImage master = MasterImage.getImage(); - Bitmap image = master.getFiltersOnlyImage(); - if (image == null) { - return; - } - GeometryMathUtils.initializeHolder(mDrawHolder, mLocalRep); - GeometryMathUtils.drawTransformedCropped(mDrawHolder, canvas, image, getWidth(), - getHeight()); - } - - public void setEditor(EditorMirror editorFlip) { - mEditorMirror = editorFlip; - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java b/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java deleted file mode 100644 index fd5714139..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImagePoint.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2013 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.imageshow; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.util.AttributeSet; - -import com.android.gallery3d.filtershow.editors.EditorRedEye; -import com.android.gallery3d.filtershow.filters.FilterPoint; -import com.android.gallery3d.filtershow.filters.FilterRedEyeRepresentation; -import com.android.gallery3d.filtershow.filters.ImageFilterRedEye; - -public abstract class ImagePoint extends ImageShow { - - private static final String LOGTAG = "ImageRedEyes"; - protected EditorRedEye mEditorRedEye; - protected FilterRedEyeRepresentation mRedEyeRep; - protected static float mTouchPadding = 80; - - public static void setTouchPadding(float padding) { - mTouchPadding = padding; - } - - public ImagePoint(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ImagePoint(Context context) { - super(context); - } - - @Override - public void resetParameter() { - ImageFilterRedEye filter = (ImageFilterRedEye) getCurrentFilter(); - if (filter != null) { - filter.clear(); - } - invalidate(); - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - Paint paint = new Paint(); - paint.setStyle(Style.STROKE); - paint.setColor(Color.RED); - paint.setStrokeWidth(2); - - Matrix originalToScreen = getImageToScreenMatrix(false); - Matrix originalRotateToScreen = getImageToScreenMatrix(true); - - if (mRedEyeRep != null) { - for (FilterPoint candidate : mRedEyeRep.getCandidates()) { - drawPoint(candidate, canvas, originalToScreen, originalRotateToScreen, paint); - } - } - } - - protected abstract void drawPoint( - FilterPoint candidate, Canvas canvas, Matrix originalToScreen, - Matrix originalRotateToScreen, Paint paint); - - public void setEditor(EditorRedEye editorRedEye) { - mEditorRedEye = editorRedEye; - } - - public void setRepresentation(FilterRedEyeRepresentation redEyeRep) { - mRedEyeRep = redEyeRep; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java b/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java deleted file mode 100644 index 40433a02e..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageRedEye.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (C) 2013 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.imageshow; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.RectF; -import android.view.MotionEvent; - -import com.android.gallery3d.filtershow.filters.FilterPoint; -import com.android.gallery3d.filtershow.filters.RedEyeCandidate; - -public class ImageRedEye extends ImagePoint { - private static final String LOGTAG = "ImageRedEyes"; - private RectF mCurrentRect = null; - - public ImageRedEye(Context context) { - super(context); - } - - @Override - public void resetParameter() { - super.resetParameter(); - invalidate(); - } - - @Override - - public boolean onTouchEvent(MotionEvent event) { - super.onTouchEvent(event); - - if (event.getPointerCount() > 1) { - return true; - } - - if (didFinishScalingOperation()) { - return true; - } - - float ex = event.getX(); - float ey = event.getY(); - - // let's transform (ex, ey) to displayed image coordinates - if (event.getAction() == MotionEvent.ACTION_DOWN) { - mCurrentRect = new RectF(); - mCurrentRect.left = ex - mTouchPadding; - mCurrentRect.top = ey - mTouchPadding; - } - if (event.getAction() == MotionEvent.ACTION_MOVE) { - mCurrentRect.right = ex + mTouchPadding; - mCurrentRect.bottom = ey + mTouchPadding; - } - if (event.getAction() == MotionEvent.ACTION_UP) { - if (mCurrentRect != null) { - // transform to original coordinates - Matrix originalNoRotateToScreen = getImageToScreenMatrix(false); - Matrix originalToScreen = getImageToScreenMatrix(true); - Matrix invert = new Matrix(); - originalToScreen.invert(invert); - RectF r = new RectF(mCurrentRect); - invert.mapRect(r); - RectF r2 = new RectF(mCurrentRect); - invert.reset(); - originalNoRotateToScreen.invert(invert); - invert.mapRect(r2); - mRedEyeRep.addRect(r, r2); - this.resetImageCaches(this); - } - mCurrentRect = null; - } - mEditorRedEye.commitLocalRepresentation(); - invalidate(); - return true; - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - Paint paint = new Paint(); - paint.setStyle(Style.STROKE); - paint.setColor(Color.RED); - paint.setStrokeWidth(2); - if (mCurrentRect != null) { - paint.setColor(Color.RED); - RectF drawRect = new RectF(mCurrentRect); - canvas.drawRect(drawRect, paint); - } - } - - @Override - protected void drawPoint(FilterPoint point, Canvas canvas, Matrix originalToScreen, - Matrix originalRotateToScreen, Paint paint) { - RedEyeCandidate candidate = (RedEyeCandidate) point; - RectF rect = candidate.getRect(); - RectF drawRect = new RectF(); - originalToScreen.mapRect(drawRect, rect); - RectF fullRect = new RectF(); - originalRotateToScreen.mapRect(fullRect, rect); - paint.setColor(Color.BLUE); - canvas.drawRect(fullRect, paint); - canvas.drawLine(fullRect.centerX(), fullRect.top, - fullRect.centerX(), fullRect.bottom, paint); - canvas.drawLine(fullRect.left, fullRect.centerY(), - fullRect.right, fullRect.centerY(), paint); - paint.setColor(Color.GREEN); - float dw = drawRect.width(); - float dh = drawRect.height(); - float dx = fullRect.centerX() - dw / 2; - float dy = fullRect.centerY() - dh / 2; - drawRect.set(dx, dy, dx + dw, dy + dh); - canvas.drawRect(drawRect, paint); - canvas.drawLine(drawRect.centerX(), drawRect.top, - drawRect.centerX(), drawRect.bottom, paint); - canvas.drawLine(drawRect.left, drawRect.centerY(), - drawRect.right, drawRect.centerY(), paint); - canvas.drawCircle(drawRect.centerX(), drawRect.centerY(), - mTouchPadding, paint); - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java b/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java deleted file mode 100644 index 5186c09d7..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageRotate.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import com.android.gallery3d.filtershow.editors.EditorRotate; -import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation; -import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; - -public class ImageRotate extends ImageShow { - private EditorRotate mEditorRotate; - private static final String TAG = ImageRotate.class.getSimpleName(); - private FilterRotateRepresentation mLocalRep = new FilterRotateRepresentation(); - private GeometryHolder mDrawHolder = new GeometryHolder(); - - public ImageRotate(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public ImageRotate(Context context) { - super(context); - } - - public void setFilterRotateRepresentation(FilterRotateRepresentation rep) { - mLocalRep = (rep == null) ? new FilterRotateRepresentation() : rep; - } - - public void rotate() { - mLocalRep.rotateCW(); - invalidate(); - } - - public FilterRotateRepresentation getFinalRepresentation() { - return mLocalRep; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // Treat event as handled. - return true; - } - - public int getLocalValue() { - return mLocalRep.getRotation().value(); - } - - @Override - public void onDraw(Canvas canvas) { - MasterImage master = MasterImage.getImage(); - Bitmap image = master.getFiltersOnlyImage(); - if (image == null) { - return; - } - GeometryMathUtils.initializeHolder(mDrawHolder, mLocalRep); - GeometryMathUtils.drawTransformedCropped(mDrawHolder, canvas, image, canvas.getWidth(), - canvas.getHeight()); - } - - public void setEditor(EditorRotate editorRotate) { - mEditorRotate = editorRotate; - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java b/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java deleted file mode 100644 index 6278b2ad4..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageShow.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.util.AttributeSet; -import android.view.GestureDetector; -import android.view.GestureDetector.OnDoubleTapListener; -import android.view.GestureDetector.OnGestureListener; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; -import android.view.View; -import android.widget.LinearLayout; - -import com.android.gallery3d.R; -import com.android.gallery3d.filtershow.FilterShowActivity; -import com.android.gallery3d.filtershow.filters.ImageFilter; -import com.android.gallery3d.filtershow.pipeline.ImagePreset; -import com.android.gallery3d.filtershow.tools.SaveImage; - -import java.io.File; - -public class ImageShow extends View implements OnGestureListener, - ScaleGestureDetector.OnScaleGestureListener, - OnDoubleTapListener { - - private static final String LOGTAG = "ImageShow"; - private static final boolean ENABLE_ZOOMED_COMPARISON = false; - - protected Paint mPaint = new Paint(); - protected int mTextSize; - protected int mTextPadding; - - protected int mBackgroundColor; - - private GestureDetector mGestureDetector = null; - private ScaleGestureDetector mScaleGestureDetector = null; - - protected Rect mImageBounds = new Rect(); - private boolean mOriginalDisabled = false; - private boolean mTouchShowOriginal = false; - private long mTouchShowOriginalDate = 0; - private final long mTouchShowOriginalDelayMin = 200; // 200ms - private int mShowOriginalDirection = 0; - private static int UNVEIL_HORIZONTAL = 1; - private static int UNVEIL_VERTICAL = 2; - - private Point mTouchDown = new Point(); - private Point mTouch = new Point(); - private boolean mFinishedScalingOperation = false; - - private int mOriginalTextMargin; - private int mOriginalTextSize; - private String mOriginalText; - private boolean mZoomIn = false; - Point mOriginalTranslation = new Point(); - float mOriginalScale; - float mStartFocusX, mStartFocusY; - private enum InteractionMode { - NONE, - SCALE, - MOVE - } - InteractionMode mInteractionMode = InteractionMode.NONE; - - private FilterShowActivity mActivity = null; - - public FilterShowActivity getActivity() { - return mActivity; - } - - public boolean hasModifications() { - return MasterImage.getImage().hasModifications(); - } - - public void resetParameter() { - // TODO: implement reset - } - - public void onNewValue(int parameter) { - invalidate(); - } - - public ImageShow(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setupImageShow(context); - } - - public ImageShow(Context context, AttributeSet attrs) { - super(context, attrs); - setupImageShow(context); - - } - - public ImageShow(Context context) { - super(context); - setupImageShow(context); - } - - private void setupImageShow(Context context) { - Resources res = context.getResources(); - mTextSize = res.getDimensionPixelSize(R.dimen.photoeditor_text_size); - mTextPadding = res.getDimensionPixelSize(R.dimen.photoeditor_text_padding); - mOriginalTextMargin = res.getDimensionPixelSize(R.dimen.photoeditor_original_text_margin); - mOriginalTextSize = res.getDimensionPixelSize(R.dimen.photoeditor_original_text_size); - mBackgroundColor = res.getColor(R.color.background_screen); - mOriginalText = res.getString(R.string.original_picture_text); - setupGestureDetector(context); - mActivity = (FilterShowActivity) context; - MasterImage.getImage().addObserver(this); - } - - public void setupGestureDetector(Context context) { - mGestureDetector = new GestureDetector(context, this); - mScaleGestureDetector = new ScaleGestureDetector(context, this); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int parentWidth = MeasureSpec.getSize(widthMeasureSpec); - int parentHeight = MeasureSpec.getSize(heightMeasureSpec); - setMeasuredDimension(parentWidth, parentHeight); - } - - public ImageFilter getCurrentFilter() { - return MasterImage.getImage().getCurrentFilter(); - } - - /* consider moving the following 2 methods into a subclass */ - /** - * This function calculates a Image to Screen Transformation matrix - * - * @param reflectRotation set true if you want the rotation encoded - * @return Image to Screen transformation matrix - */ - protected Matrix getImageToScreenMatrix(boolean reflectRotation) { - MasterImage master = MasterImage.getImage(); - if (master.getOriginalBounds() == null) { - return new Matrix(); - } - Matrix m = GeometryMathUtils.getImageToScreenMatrix(master.getPreset().getGeometryFilters(), - reflectRotation, master.getOriginalBounds(), getWidth(), getHeight()); - Point translate = master.getTranslation(); - float scaleFactor = master.getScaleFactor(); - m.postTranslate(translate.x, translate.y); - m.postScale(scaleFactor, scaleFactor, getWidth() / 2.0f, getHeight() / 2.0f); - return m; - } - - /** - * This function calculates a to Screen Image Transformation matrix - * - * @param reflectRotation set true if you want the rotation encoded - * @return Screen to Image transformation matrix - */ - protected Matrix getScreenToImageMatrix(boolean reflectRotation) { - Matrix m = getImageToScreenMatrix(reflectRotation); - Matrix invert = new Matrix(); - m.invert(invert); - return invert; - } - - public ImagePreset getImagePreset() { - return MasterImage.getImage().getPreset(); - } - - @Override - public void onDraw(Canvas canvas) { - MasterImage.getImage().setImageShowSize(getWidth(), getHeight()); - - float cx = canvas.getWidth()/2.0f; - float cy = canvas.getHeight()/2.0f; - float scaleFactor = MasterImage.getImage().getScaleFactor(); - Point translation = MasterImage.getImage().getTranslation(); - - Matrix scalingMatrix = new Matrix(); - scalingMatrix.postScale(scaleFactor, scaleFactor, cx, cy); - scalingMatrix.preTranslate(translation.x, translation.y); - - RectF unscaledClipRect = new RectF(mImageBounds); - scalingMatrix.mapRect(unscaledClipRect, unscaledClipRect); - - canvas.save(); - - boolean enablePartialRendering = false; - - // For now, partial rendering is disabled for all filters, - // so no need to clip. - if (enablePartialRendering && !unscaledClipRect.isEmpty()) { - canvas.clipRect(unscaledClipRect); - } - - canvas.save(); - // TODO: center scale on gesture - canvas.scale(scaleFactor, scaleFactor, cx, cy); - canvas.translate(translation.x, translation.y); - drawImage(canvas, getFilteredImage(), true); - Bitmap highresPreview = MasterImage.getImage().getHighresImage(); - if (highresPreview != null) { - drawImage(canvas, highresPreview, true); - } - canvas.restore(); - - Bitmap partialPreview = MasterImage.getImage().getPartialImage(); - if (partialPreview != null) { - Rect src = new Rect(0, 0, partialPreview.getWidth(), partialPreview.getHeight()); - Rect dest = new Rect(0, 0, getWidth(), getHeight()); - canvas.drawBitmap(partialPreview, src, dest, mPaint); - } - - canvas.save(); - canvas.scale(scaleFactor, scaleFactor, cx, cy); - canvas.translate(translation.x, translation.y); - drawPartialImage(canvas, getGeometryOnlyImage()); - canvas.restore(); - - canvas.restore(); - } - - public void resetImageCaches(ImageShow caller) { - MasterImage.getImage().updatePresets(true); - } - - public Bitmap getFiltersOnlyImage() { - return MasterImage.getImage().getFiltersOnlyImage(); - } - - public Bitmap getGeometryOnlyImage() { - return MasterImage.getImage().getGeometryOnlyImage(); - } - - public Bitmap getFilteredImage() { - return MasterImage.getImage().getFilteredImage(); - } - - public void drawImage(Canvas canvas, Bitmap image, boolean updateBounds) { - if (image != null) { - Rect s = new Rect(0, 0, image.getWidth(), - image.getHeight()); - - float scale = GeometryMathUtils.scale(image.getWidth(), image.getHeight(), getWidth(), - getHeight()); - - float w = image.getWidth() * scale; - float h = image.getHeight() * scale; - float ty = (getHeight() - h) / 2.0f; - float tx = (getWidth() - w) / 2.0f; - - Rect d = new Rect((int) tx, (int) ty, (int) (w + tx), - (int) (h + ty)); - if (updateBounds) { - mImageBounds = d; - } - canvas.drawBitmap(image, s, d, mPaint); - } - } - - public void drawPartialImage(Canvas canvas, Bitmap image) { - boolean showsOriginal = MasterImage.getImage().showsOriginal(); - if (!showsOriginal && !mTouchShowOriginal) - return; - canvas.save(); - if (image != null) { - if (mShowOriginalDirection == 0) { - if (Math.abs(mTouch.y - mTouchDown.y) > Math.abs(mTouch.x - mTouchDown.x)) { - mShowOriginalDirection = UNVEIL_VERTICAL; - } else { - mShowOriginalDirection = UNVEIL_HORIZONTAL; - } - } - - int px = 0; - int py = 0; - if (mShowOriginalDirection == UNVEIL_VERTICAL) { - px = mImageBounds.width(); - py = mTouch.y - mImageBounds.top; - } else { - px = mTouch.x - mImageBounds.left; - py = mImageBounds.height(); - if (showsOriginal) { - px = mImageBounds.width(); - } - } - - Rect d = new Rect(mImageBounds.left, mImageBounds.top, - mImageBounds.left + px, mImageBounds.top + py); - canvas.clipRect(d); - drawImage(canvas, image, false); - Paint paint = new Paint(); - paint.setColor(Color.BLACK); - paint.setStrokeWidth(3); - - if (mShowOriginalDirection == UNVEIL_VERTICAL) { - canvas.drawLine(mImageBounds.left, mTouch.y, - mImageBounds.right, mTouch.y, paint); - } else { - canvas.drawLine(mTouch.x, mImageBounds.top, - mTouch.x, mImageBounds.bottom, paint); - } - - Rect bounds = new Rect(); - paint.setAntiAlias(true); - paint.setTextSize(mOriginalTextSize); - paint.getTextBounds(mOriginalText, 0, mOriginalText.length(), bounds); - paint.setColor(Color.BLACK); - paint.setStyle(Paint.Style.STROKE); - paint.setStrokeWidth(3); - canvas.drawText(mOriginalText, mImageBounds.left + mOriginalTextMargin, - mImageBounds.top + bounds.height() + mOriginalTextMargin, paint); - paint.setStyle(Paint.Style.FILL); - paint.setStrokeWidth(1); - paint.setColor(Color.WHITE); - canvas.drawText(mOriginalText, mImageBounds.left + mOriginalTextMargin, - mImageBounds.top + bounds.height() + mOriginalTextMargin, paint); - } - canvas.restore(); - } - - public void bindAsImageLoadListener() { - MasterImage.getImage().addListener(this); - } - - public void updateImage() { - invalidate(); - } - - public void imageLoaded() { - updateImage(); - } - - public void saveImage(FilterShowActivity filterShowActivity, File file) { - SaveImage.saveImage(getImagePreset(), filterShowActivity, file); - } - - - public boolean scaleInProgress() { - return mScaleGestureDetector.isInProgress(); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - super.onTouchEvent(event); - int action = event.getAction(); - action = action & MotionEvent.ACTION_MASK; - - mGestureDetector.onTouchEvent(event); - boolean scaleInProgress = scaleInProgress(); - mScaleGestureDetector.onTouchEvent(event); - if (mInteractionMode == InteractionMode.SCALE) { - return true; - } - if (!scaleInProgress() && scaleInProgress) { - // If we were scaling, the scale will stop but we will - // still issue an ACTION_UP. Let the subclasses know. - mFinishedScalingOperation = true; - } - - int ex = (int) event.getX(); - int ey = (int) event.getY(); - if (action == MotionEvent.ACTION_DOWN) { - mInteractionMode = InteractionMode.MOVE; - mTouchDown.x = ex; - mTouchDown.y = ey; - mTouchShowOriginalDate = System.currentTimeMillis(); - mShowOriginalDirection = 0; - MasterImage.getImage().setOriginalTranslation(MasterImage.getImage().getTranslation()); - } - - if (action == MotionEvent.ACTION_MOVE && mInteractionMode == InteractionMode.MOVE) { - mTouch.x = ex; - mTouch.y = ey; - - float scaleFactor = MasterImage.getImage().getScaleFactor(); - if (scaleFactor > 1 && (!ENABLE_ZOOMED_COMPARISON || event.getPointerCount() == 2)) { - float translateX = (mTouch.x - mTouchDown.x) / scaleFactor; - float translateY = (mTouch.y - mTouchDown.y) / scaleFactor; - Point originalTranslation = MasterImage.getImage().getOriginalTranslation(); - Point translation = MasterImage.getImage().getTranslation(); - translation.x = (int) (originalTranslation.x + translateX); - translation.y = (int) (originalTranslation.y + translateY); - constrainTranslation(translation, scaleFactor); - MasterImage.getImage().setTranslation(translation); - mTouchShowOriginal = false; - } else if (enableComparison() && !mOriginalDisabled - && (System.currentTimeMillis() - mTouchShowOriginalDate - > mTouchShowOriginalDelayMin) - && event.getPointerCount() == 1) { - mTouchShowOriginal = true; - } - } - - if (action == MotionEvent.ACTION_UP) { - mInteractionMode = InteractionMode.NONE; - mTouchShowOriginal = false; - mTouchDown.x = 0; - mTouchDown.y = 0; - mTouch.x = 0; - mTouch.y = 0; - if (MasterImage.getImage().getScaleFactor() <= 1) { - MasterImage.getImage().setScaleFactor(1); - MasterImage.getImage().resetTranslation(); - } - } - invalidate(); - return true; - } - - protected boolean enableComparison() { - return true; - } - - @Override - public boolean onDoubleTap(MotionEvent arg0) { - mZoomIn = !mZoomIn; - float scale = 1.0f; - if (mZoomIn) { - scale = MasterImage.getImage().getMaxScaleFactor(); - } - if (scale != MasterImage.getImage().getScaleFactor()) { - MasterImage.getImage().setScaleFactor(scale); - float translateX = (getWidth() / 2 - arg0.getX()); - float translateY = (getHeight() / 2 - arg0.getY()); - Point translation = MasterImage.getImage().getTranslation(); - translation.x = (int) (mOriginalTranslation.x + translateX); - translation.y = (int) (mOriginalTranslation.y + translateY); - constrainTranslation(translation, scale); - MasterImage.getImage().setTranslation(translation); - invalidate(); - } - return true; - } - - private void constrainTranslation(Point translation, float scale) { - float maxTranslationX = getWidth() / scale; - float maxTranslationY = getHeight() / scale; - if (Math.abs(translation.x) > maxTranslationX) { - translation.x = (int) (Math.signum(translation.x) * - maxTranslationX); - if (Math.abs(translation.y) > maxTranslationY) { - translation.y = (int) (Math.signum(translation.y) * - maxTranslationY); - } - - } - } - - @Override - public boolean onDoubleTapEvent(MotionEvent arg0) { - return false; - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent arg0) { - return false; - } - - @Override - public boolean onDown(MotionEvent arg0) { - return false; - } - - @Override - public boolean onFling(MotionEvent startEvent, MotionEvent endEvent, float arg2, float arg3) { - if (mActivity == null) { - return false; - } - if (endEvent.getPointerCount() == 2) { - return false; - } - return true; - } - - @Override - public void onLongPress(MotionEvent arg0) { - } - - @Override - public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) { - return false; - } - - @Override - public void onShowPress(MotionEvent arg0) { - } - - @Override - public boolean onSingleTapUp(MotionEvent arg0) { - return false; - } - - public boolean useUtilityPanel() { - return false; - } - - public void openUtilityPanel(final LinearLayout accessoryViewList) { - } - - @Override - public boolean onScale(ScaleGestureDetector detector) { - MasterImage img = MasterImage.getImage(); - float scaleFactor = img.getScaleFactor(); - - scaleFactor = scaleFactor * detector.getScaleFactor(); - if (scaleFactor > MasterImage.getImage().getMaxScaleFactor()) { - scaleFactor = MasterImage.getImage().getMaxScaleFactor(); - } - if (scaleFactor < 0.5) { - scaleFactor = 0.5f; - } - MasterImage.getImage().setScaleFactor(scaleFactor); - scaleFactor = img.getScaleFactor(); - float focusx = detector.getFocusX(); - float focusy = detector.getFocusY(); - float translateX = (focusx - mStartFocusX) / scaleFactor; - float translateY = (focusy - mStartFocusY) / scaleFactor; - Point translation = MasterImage.getImage().getTranslation(); - translation.x = (int) (mOriginalTranslation.x + translateX); - translation.y = (int) (mOriginalTranslation.y + translateY); - constrainTranslation(translation, scaleFactor); - MasterImage.getImage().setTranslation(translation); - - invalidate(); - return true; - } - - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - Point pos = MasterImage.getImage().getTranslation(); - mOriginalTranslation.x = pos.x; - mOriginalTranslation.y = pos.y; - mOriginalScale = MasterImage.getImage().getScaleFactor(); - mStartFocusX = detector.getFocusX(); - mStartFocusY = detector.getFocusY(); - mInteractionMode = InteractionMode.SCALE; - return true; - } - - @Override - public void onScaleEnd(ScaleGestureDetector detector) { - mInteractionMode = InteractionMode.NONE; - if (MasterImage.getImage().getScaleFactor() < 1) { - MasterImage.getImage().setScaleFactor(1); - invalidate(); - } - } - - public boolean didFinishScalingOperation() { - if (mFinishedScalingOperation) { - mFinishedScalingOperation = false; - return true; - } - return false; - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java b/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java deleted file mode 100644 index ff75dcc09..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageStraighten.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Matrix; -import android.graphics.Paint; -import android.graphics.Paint.Style; -import android.graphics.Path; -import android.graphics.RectF; -import android.util.AttributeSet; -import android.view.MotionEvent; - -import com.android.gallery3d.filtershow.editors.EditorStraighten; -import com.android.gallery3d.filtershow.filters.FilterCropRepresentation; -import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation; -import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils.GeometryHolder; - -import java.util.ArrayList; -import java.util.Collection; - - -public class ImageStraighten extends ImageShow { - private static final String TAG = ImageStraighten.class.getSimpleName(); - private float mBaseAngle = 0; - private float mAngle = 0; - private float mInitialAngle = 0; - private boolean mFirstDrawSinceUp = false; - private EditorStraighten mEditorStraighten; - private FilterStraightenRepresentation mLocalRep = new FilterStraightenRepresentation(); - private RectF mPriorCropAtUp = new RectF(); - private RectF mDrawRect = new RectF(); - private Path mDrawPath = new Path(); - private GeometryHolder mDrawHolder = new GeometryHolder(); - private enum MODES { - NONE, MOVE - } - private MODES mState = MODES.NONE; - private static final float MAX_STRAIGHTEN_ANGLE - = FilterStraightenRepresentation.MAX_STRAIGHTEN_ANGLE; - private static final float MIN_STRAIGHTEN_ANGLE - = FilterStraightenRepresentation.MIN_STRAIGHTEN_ANGLE; - private float mCurrentX; - private float mCurrentY; - private float mTouchCenterX; - private float mTouchCenterY; - private RectF mCrop = new RectF(); - private final Paint mPaint = new Paint(); - - public ImageStraighten(Context context) { - super(context); - } - - public ImageStraighten(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void setFilterStraightenRepresentation(FilterStraightenRepresentation rep) { - mLocalRep = (rep == null) ? new FilterStraightenRepresentation() : rep; - mInitialAngle = mBaseAngle = mAngle = mLocalRep.getStraighten(); - } - - public Collection<FilterRepresentation> getFinalRepresentation() { - ArrayList<FilterRepresentation> reps = new ArrayList<FilterRepresentation>(2); - reps.add(mLocalRep); - if (mInitialAngle != mLocalRep.getStraighten()) { - reps.add(new FilterCropRepresentation(mCrop)); - } - return reps; - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - - switch (event.getActionMasked()) { - case (MotionEvent.ACTION_DOWN): - if (mState == MODES.NONE) { - mTouchCenterX = x; - mTouchCenterY = y; - mCurrentX = x; - mCurrentY = y; - mState = MODES.MOVE; - mBaseAngle = mAngle; - } - break; - case (MotionEvent.ACTION_UP): - if (mState == MODES.MOVE) { - mState = MODES.NONE; - mCurrentX = x; - mCurrentY = y; - computeValue(); - mFirstDrawSinceUp = true; - } - break; - case (MotionEvent.ACTION_MOVE): - if (mState == MODES.MOVE) { - mCurrentX = x; - mCurrentY = y; - computeValue(); - } - break; - default: - break; - } - invalidate(); - return true; - } - - private static float angleFor(float dx, float dy) { - return (float) (Math.atan2(dx, dy) * 180 / Math.PI); - } - - private float getCurrentTouchAngle() { - float centerX = getWidth() / 2f; - float centerY = getHeight() / 2f; - if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) { - return 0; - } - float dX1 = mTouchCenterX - centerX; - float dY1 = mTouchCenterY - centerY; - float dX2 = mCurrentX - centerX; - float dY2 = mCurrentY - centerY; - float angleA = angleFor(dX1, dY1); - float angleB = angleFor(dX2, dY2); - return (angleB - angleA) % 360; - } - - private void computeValue() { - float angle = getCurrentTouchAngle(); - mAngle = (mBaseAngle - angle) % 360; - mAngle = Math.max(MIN_STRAIGHTEN_ANGLE, mAngle); - mAngle = Math.min(MAX_STRAIGHTEN_ANGLE, mAngle); - } - - private static void getUntranslatedStraightenCropBounds(RectF outRect, float straightenAngle) { - float deg = straightenAngle; - if (deg < 0) { - deg = -deg; - } - double a = Math.toRadians(deg); - double sina = Math.sin(a); - double cosa = Math.cos(a); - double rw = outRect.width(); - double rh = outRect.height(); - double h1 = rh * rh / (rw * sina + rh * cosa); - double h2 = rh * rw / (rw * cosa + rh * sina); - double hh = Math.min(h1, h2); - double ww = hh * rw / rh; - float left = (float) ((rw - ww) * 0.5f); - float top = (float) ((rh - hh) * 0.5f); - float right = (float) (left + ww); - float bottom = (float) (top + hh); - outRect.set(left, top, right, bottom); - } - - private void updateCurrentCrop(Matrix m, GeometryHolder h, RectF tmp, int imageWidth, - int imageHeight, int viewWidth, int viewHeight) { - if (GeometryMathUtils.needsDimensionSwap(h.rotation)) { - tmp.set(0, 0, imageHeight, imageWidth); - } else { - tmp.set(0, 0, imageWidth, imageHeight); - } - float scale = GeometryMathUtils.scale(imageWidth, imageHeight, viewWidth, viewHeight); - GeometryMathUtils.scaleRect(tmp, scale); - getUntranslatedStraightenCropBounds(tmp, mAngle); - tmp.offset(viewWidth / 2f - tmp.centerX(), viewHeight / 2f - tmp.centerY()); - h.straighten = 0; - Matrix m1 = GeometryMathUtils.getFullGeometryToScreenMatrix(h, imageWidth, - imageHeight, viewWidth, viewHeight); - m.reset(); - m1.invert(m); - mCrop.set(tmp); - m.mapRect(mCrop); - FilterCropRepresentation.findNormalizedCrop(mCrop, imageWidth, imageHeight); - } - - - @Override - public void onDraw(Canvas canvas) { - MasterImage master = MasterImage.getImage(); - Bitmap image = master.getFiltersOnlyImage(); - if (image == null) { - return; - } - GeometryMathUtils.initializeHolder(mDrawHolder, mLocalRep); - mDrawHolder.straighten = mAngle; - int imageWidth = image.getWidth(); - int imageHeight = image.getHeight(); - int viewWidth = canvas.getWidth(); - int viewHeight = canvas.getHeight(); - - // Get matrix for drawing bitmap - Matrix m = GeometryMathUtils.getFullGeometryToScreenMatrix(mDrawHolder, imageWidth, - imageHeight, viewWidth, viewHeight); - mPaint.reset(); - mPaint.setAntiAlias(true); - mPaint.setFilterBitmap(true); - canvas.drawBitmap(image, m, mPaint); - - mPaint.setFilterBitmap(false); - mPaint.setColor(Color.WHITE); - mPaint.setStrokeWidth(2); - mPaint.setStyle(Paint.Style.FILL_AND_STROKE); - updateCurrentCrop(m, mDrawHolder, mDrawRect, imageWidth, - imageHeight, viewWidth, viewHeight); - if (mFirstDrawSinceUp) { - mPriorCropAtUp.set(mCrop); - mLocalRep.setStraighten(mAngle); - mFirstDrawSinceUp = false; - } - - // Draw the grid - if (mState == MODES.MOVE) { - canvas.save(); - canvas.clipRect(mDrawRect); - int n = 16; - float step = viewWidth / n; - float p = 0; - for (int i = 1; i < n; i++) { - p = i * step; - mPaint.setAlpha(60); - canvas.drawLine(p, 0, p, viewHeight, mPaint); - canvas.drawLine(0, p, viewHeight, p, mPaint); - } - canvas.restore(); - } - mPaint.reset(); - mPaint.setColor(Color.WHITE); - mPaint.setStyle(Style.STROKE); - mPaint.setStrokeWidth(3); - mDrawPath.reset(); - mDrawPath.addRect(mDrawRect, Path.Direction.CW); - canvas.drawPath(mDrawPath, mPaint); - } - - public void setEditor(EditorStraighten editorStraighten) { - mEditorStraighten = editorStraighten; - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java b/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java deleted file mode 100644 index 25a0a9073..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageTinyPlanet.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * 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.imageshow; - -import android.content.Context; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.RectF; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.ScaleGestureDetector; -import android.view.ScaleGestureDetector.OnScaleGestureListener; - -import com.android.gallery3d.filtershow.editors.BasicEditor; -import com.android.gallery3d.filtershow.editors.EditorTinyPlanet; -import com.android.gallery3d.filtershow.filters.FilterTinyPlanetRepresentation; - -public class ImageTinyPlanet extends ImageShow { - private static final String LOGTAG = "ImageTinyPlanet"; - - private float mTouchCenterX = 0; - private float mTouchCenterY = 0; - private float mCurrentX = 0; - private float mCurrentY = 0; - private float mCenterX = 0; - private float mCenterY = 0; - private float mStartAngle = 0; - private FilterTinyPlanetRepresentation mTinyPlanetRep; - private EditorTinyPlanet mEditorTinyPlanet; - private ScaleGestureDetector mScaleGestureDetector = null; - boolean mInScale = false; - RectF mDestRect = new RectF(); - - OnScaleGestureListener mScaleGestureListener = new OnScaleGestureListener() { - private float mScale = 100; - @Override - public void onScaleEnd(ScaleGestureDetector detector) { - mInScale = false; - } - - @Override - public boolean onScaleBegin(ScaleGestureDetector detector) { - mInScale = true; - mScale = mTinyPlanetRep.getValue(); - return true; - } - - @Override - public boolean onScale(ScaleGestureDetector detector) { - int value = mTinyPlanetRep.getValue(); - mScale *= detector.getScaleFactor(); - value = (int) (mScale); - value = Math.min(mTinyPlanetRep.getMaximum(), value); - value = Math.max(mTinyPlanetRep.getMinimum(), value); - mTinyPlanetRep.setValue(value); - invalidate(); - mEditorTinyPlanet.commitLocalRepresentation(); - mEditorTinyPlanet.updateUI(); - return true; - } - }; - - public ImageTinyPlanet(Context context) { - super(context); - mScaleGestureDetector = new ScaleGestureDetector(context, mScaleGestureListener); - } - - public ImageTinyPlanet(Context context, AttributeSet attrs) { - super(context, attrs); - mScaleGestureDetector = new ScaleGestureDetector(context,mScaleGestureListener ); - } - - protected static float angleFor(float dx, float dy) { - return (float) (Math.atan2(dx, dy) * 180 / Math.PI); - } - - protected float getCurrentTouchAngle() { - if (mCurrentX == mTouchCenterX && mCurrentY == mTouchCenterY) { - return 0; - } - float dX1 = mTouchCenterX - mCenterX; - float dY1 = mTouchCenterY - mCenterY; - float dX2 = mCurrentX - mCenterX; - float dY2 = mCurrentY - mCenterY; - - float angleA = angleFor(dX1, dY1); - float angleB = angleFor(dX2, dY2); - return (float) (((angleB - angleA) % 360) * Math.PI / 180); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - float x = event.getX(); - float y = event.getY(); - mCurrentX = x; - mCurrentY = y; - mCenterX = getWidth() / 2; - mCenterY = getHeight() / 2; - mScaleGestureDetector.onTouchEvent(event); - if (mInScale) { - return true; - } - switch (event.getActionMasked()) { - case (MotionEvent.ACTION_DOWN): - mTouchCenterX = x; - mTouchCenterY = y; - mStartAngle = mTinyPlanetRep.getAngle(); - break; - - case (MotionEvent.ACTION_MOVE): - mTinyPlanetRep.setAngle(mStartAngle + getCurrentTouchAngle()); - break; - } - invalidate(); - mEditorTinyPlanet.commitLocalRepresentation(); - return true; - } - - public void setRepresentation(FilterTinyPlanetRepresentation tinyPlanetRep) { - mTinyPlanetRep = tinyPlanetRep; - } - - public void setEditor(BasicEditor editorTinyPlanet) { - mEditorTinyPlanet = (EditorTinyPlanet) editorTinyPlanet; - } - - @Override - public void onDraw(Canvas canvas) { - Bitmap bitmap = MasterImage.getImage().getHighresImage(); - if (bitmap == null) { - bitmap = MasterImage.getImage().getFilteredImage(); - } - - if (bitmap != null) { - display(canvas, bitmap); - } - } - - private void display(Canvas canvas, Bitmap bitmap) { - float sw = canvas.getWidth(); - float sh = canvas.getHeight(); - float iw = bitmap.getWidth(); - float ih = bitmap.getHeight(); - float nsw = sw; - float nsh = sh; - - if (sw * ih > sh * iw) { - nsw = sh * iw / ih; - } else { - nsh = sw * ih / iw; - } - - mDestRect.left = (sw - nsw) / 2; - mDestRect.top = (sh - nsh) / 2; - mDestRect.right = sw - mDestRect.left; - mDestRect.bottom = sh - mDestRect.top; - - canvas.drawBitmap(bitmap, null, mDestRect, mPaint); - } -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java b/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java deleted file mode 100644 index 518969ee1..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/ImageVignette.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2013 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.imageshow; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.util.AttributeSet; -import android.util.Log; -import android.view.MotionEvent; - -import com.android.gallery3d.filtershow.editors.EditorVignette; -import com.android.gallery3d.filtershow.filters.FilterVignetteRepresentation; - -public class ImageVignette extends ImageShow { - private static final String LOGTAG = "ImageVignette"; - - private FilterVignetteRepresentation mVignetteRep; - private EditorVignette mEditorVignette; - - private int mActiveHandle = -1; - - EclipseControl mElipse; - - public ImageVignette(Context context) { - super(context); - mElipse = new EclipseControl(context); - } - - public ImageVignette(Context context, AttributeSet attrs) { - super(context, attrs); - mElipse = new EclipseControl(context); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - int mask = event.getActionMasked(); - if (mActiveHandle == -1) { - if (MotionEvent.ACTION_DOWN != mask) { - return super.onTouchEvent(event); - } - if (event.getPointerCount() == 1) { - mActiveHandle = mElipse.getCloseHandle(event.getX(), event.getY()); - } - if (mActiveHandle == -1) { - return super.onTouchEvent(event); - } - } else { - switch (mask) { - case MotionEvent.ACTION_UP: - mActiveHandle = -1; - break; - case MotionEvent.ACTION_DOWN: - break; - } - } - float x = event.getX(); - float y = event.getY(); - - mElipse.setScrToImageMatrix(getScreenToImageMatrix(true)); - - boolean didComputeEllipses = false; - switch (mask) { - case (MotionEvent.ACTION_DOWN): - mElipse.actionDown(x, y, mVignetteRep); - break; - case (MotionEvent.ACTION_UP): - case (MotionEvent.ACTION_MOVE): - mElipse.actionMove(mActiveHandle, x, y, mVignetteRep); - setRepresentation(mVignetteRep); - didComputeEllipses = true; - break; - } - if (!didComputeEllipses) { - computeEllipses(); - } - invalidate(); - return true; - } - - public void setRepresentation(FilterVignetteRepresentation vignetteRep) { - mVignetteRep = vignetteRep; - computeEllipses(); - } - - public void computeEllipses() { - if (mVignetteRep == null) { - return; - } - Matrix toImg = getScreenToImageMatrix(false); - Matrix toScr = new Matrix(); - toImg.invert(toScr); - - float[] c = new float[] { - mVignetteRep.getCenterX(), mVignetteRep.getCenterY() }; - if (Float.isNaN(c[0])) { - float cx = MasterImage.getImage().getOriginalBounds().width() / 2; - float cy = MasterImage.getImage().getOriginalBounds().height() / 2; - float rx = Math.min(cx, cy) * .8f; - float ry = rx; - mVignetteRep.setCenter(cx, cy); - mVignetteRep.setRadius(rx, ry); - - c[0] = cx; - c[1] = cy; - toScr.mapPoints(c); - if (getWidth() != 0) { - mElipse.setCenter(c[0], c[1]); - mElipse.setRadius(c[0] * 0.8f, c[1] * 0.8f); - } - } else { - - toScr.mapPoints(c); - - mElipse.setCenter(c[0], c[1]); - mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX()), - toScr.mapRadius(mVignetteRep.getRadiusY())); - } - mEditorVignette.commitLocalRepresentation(); - } - - public void setEditor(EditorVignette editorVignette) { - mEditorVignette = editorVignette; - } - - @Override - public void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - computeEllipses(); - } - - @Override - public void onDraw(Canvas canvas) { - super.onDraw(canvas); - if (mVignetteRep == null) { - return; - } - Matrix toImg = getScreenToImageMatrix(false); - Matrix toScr = new Matrix(); - toImg.invert(toScr); - float[] c = new float[] { - mVignetteRep.getCenterX(), mVignetteRep.getCenterY() }; - toScr.mapPoints(c); - mElipse.setCenter(c[0], c[1]); - mElipse.setRadius(toScr.mapRadius(mVignetteRep.getRadiusX()), - toScr.mapRadius(mVignetteRep.getRadiusY())); - - mElipse.draw(canvas); - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/Line.java b/src/com/android/gallery3d/filtershow/imageshow/Line.java deleted file mode 100644 index a767bd809..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/Line.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.imageshow; - -public interface Line { - void setPoint1(float x, float y); - void setPoint2(float x, float y); - float getPoint1X(); - float getPoint1Y(); - float getPoint2X(); - float getPoint2Y(); -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java b/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java deleted file mode 100644 index 92e57bfc1..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/MasterImage.java +++ /dev/null @@ -1,581 +0,0 @@ -/* - * Copyright (C) 2013 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.imageshow; - -import android.graphics.Bitmap; -import android.graphics.Matrix; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.net.Uri; -import android.os.Handler; -import android.os.Message; - -import com.android.gallery3d.filtershow.FilterShowActivity; -import com.android.gallery3d.filtershow.cache.ImageLoader; -import com.android.gallery3d.filtershow.filters.FilterRepresentation; -import com.android.gallery3d.filtershow.filters.ImageFilter; -import com.android.gallery3d.filtershow.history.HistoryItem; -import com.android.gallery3d.filtershow.history.HistoryManager; -import com.android.gallery3d.filtershow.pipeline.Buffer; -import com.android.gallery3d.filtershow.pipeline.ImagePreset; -import com.android.gallery3d.filtershow.pipeline.RenderingRequest; -import com.android.gallery3d.filtershow.pipeline.RenderingRequestCaller; -import com.android.gallery3d.filtershow.pipeline.SharedBuffer; -import com.android.gallery3d.filtershow.pipeline.SharedPreset; -import com.android.gallery3d.filtershow.state.StateAdapter; - -import java.util.Vector; - -public class MasterImage implements RenderingRequestCaller { - - private static final String LOGTAG = "MasterImage"; - private boolean DEBUG = false; - private static final boolean DISABLEZOOM = false; - public static final int SMALL_BITMAP_DIM = 160; - public static final int MAX_BITMAP_DIM = 900; - private static MasterImage sMasterImage = null; - - private boolean mSupportsHighRes = false; - - private ImageFilter mCurrentFilter = null; - private ImagePreset mPreset = null; - private ImagePreset mLoadedPreset = null; - private ImagePreset mGeometryOnlyPreset = null; - private ImagePreset mFiltersOnlyPreset = null; - - private SharedBuffer mPreviewBuffer = new SharedBuffer(); - private SharedPreset mPreviewPreset = new SharedPreset(); - - private Bitmap mOriginalBitmapSmall = null; - private Bitmap mOriginalBitmapLarge = null; - private Bitmap mOriginalBitmapHighres = null; - private int mOrientation; - private Rect mOriginalBounds; - private final Vector<ImageShow> mLoadListeners = new Vector<ImageShow>(); - private Uri mUri = null; - private int mZoomOrientation = ImageLoader.ORI_NORMAL; - - private Bitmap mGeometryOnlyBitmap = null; - private Bitmap mFiltersOnlyBitmap = null; - private Bitmap mPartialBitmap = null; - private Bitmap mHighresBitmap = null; - - private HistoryManager mHistory = null; - private StateAdapter mState = null; - - private FilterShowActivity mActivity = null; - - private Vector<ImageShow> mObservers = new Vector<ImageShow>(); - private FilterRepresentation mCurrentFilterRepresentation; - - private float mScaleFactor = 1.0f; - private float mMaxScaleFactor = 3.0f; // TODO: base this on the current view / image - private Point mTranslation = new Point(); - private Point mOriginalTranslation = new Point(); - - private Point mImageShowSize = new Point(); - - private boolean mShowsOriginal; - - private MasterImage() { - } - - // TODO: remove singleton - public static void setMaster(MasterImage master) { - sMasterImage = master; - } - - public static MasterImage getImage() { - if (sMasterImage == null) { - sMasterImage = new MasterImage(); - } - return sMasterImage; - } - - public Bitmap getOriginalBitmapSmall() { - return mOriginalBitmapSmall; - } - - public Bitmap getOriginalBitmapLarge() { - return mOriginalBitmapLarge; - } - - public Bitmap getOriginalBitmapHighres() { - return mOriginalBitmapHighres; - } - - public void setOriginalBitmapHighres(Bitmap mOriginalBitmapHighres) { - this.mOriginalBitmapHighres = mOriginalBitmapHighres; - } - - public int getOrientation() { - return mOrientation; - } - - public Rect getOriginalBounds() { - return mOriginalBounds; - } - - public void setOriginalBounds(Rect r) { - mOriginalBounds = r; - } - - public Uri getUri() { - return mUri; - } - - public void setUri(Uri uri) { - mUri = uri; - } - - public int getZoomOrientation() { - return mZoomOrientation; - } - - public void addListener(ImageShow imageShow) { - if (!mLoadListeners.contains(imageShow)) { - mLoadListeners.add(imageShow); - } - } - - public void warnListeners() { - mActivity.runOnUiThread(mWarnListenersRunnable); - } - - private Runnable mWarnListenersRunnable = new Runnable() { - @Override - public void run() { - for (int i = 0; i < mLoadListeners.size(); i++) { - ImageShow imageShow = mLoadListeners.elementAt(i); - imageShow.imageLoaded(); - } - invalidatePreview(); - } - }; - - public boolean loadBitmap(Uri uri, int size) { - setUri(uri); - mOrientation = ImageLoader.getMetadataOrientation(mActivity, uri); - Rect originalBounds = new Rect(); - mOriginalBitmapLarge = ImageLoader.loadOrientedConstrainedBitmap(uri, mActivity, - Math.min(MAX_BITMAP_DIM, size), - mOrientation, originalBounds); - setOriginalBounds(originalBounds); - if (mOriginalBitmapLarge == null) { - return false; - } - int sw = SMALL_BITMAP_DIM; - int sh = (int) (sw * (float) mOriginalBitmapLarge.getHeight() / mOriginalBitmapLarge - .getWidth()); - mOriginalBitmapSmall = Bitmap.createScaledBitmap(mOriginalBitmapLarge, sw, sh, true); - mZoomOrientation = mOrientation; - warnListeners(); - return true; - } - - public void setSupportsHighRes(boolean value) { - mSupportsHighRes = value; - } - - public void addObserver(ImageShow observer) { - if (mObservers.contains(observer)) { - return; - } - mObservers.add(observer); - } - - public void setActivity(FilterShowActivity activity) { - mActivity = activity; - } - - public FilterShowActivity getActivity() { - return mActivity; - } - - public synchronized ImagePreset getPreset() { - return mPreset; - } - - public synchronized ImagePreset getGeometryPreset() { - return mGeometryOnlyPreset; - } - - public synchronized ImagePreset getFiltersOnlyPreset() { - return mFiltersOnlyPreset; - } - - public synchronized void setPreset(ImagePreset preset, - FilterRepresentation change, - boolean addToHistory) { - if (DEBUG) { - preset.showFilters(); - } - mPreset = preset; - mPreset.fillImageStateAdapter(mState); - if (addToHistory) { - HistoryItem historyItem = new HistoryItem(mPreset, change); - mHistory.addHistoryItem(historyItem); - } - updatePresets(true); - mActivity.updateCategories(); - } - - public void onHistoryItemClick(int position) { - HistoryItem historyItem = mHistory.getItem(position); - // We need a copy from the history - ImagePreset newPreset = new ImagePreset(historyItem.getImagePreset()); - // don't need to add it to the history - setPreset(newPreset, historyItem.getFilterRepresentation(), false); - mHistory.setCurrentPreset(position); - } - - public HistoryManager getHistory() { - return mHistory; - } - - public StateAdapter getState() { - return mState; - } - - public void setHistoryManager(HistoryManager adapter) { - mHistory = adapter; - } - - public void setStateAdapter(StateAdapter adapter) { - mState = adapter; - } - - public void setCurrentFilter(ImageFilter filter) { - mCurrentFilter = filter; - } - - public ImageFilter getCurrentFilter() { - return mCurrentFilter; - } - - public synchronized boolean hasModifications() { - // TODO: We need to have a better same effects check to see if two - // presets are functionally the same. Right now, we are relying on a - // stricter check as equals(). - ImagePreset loadedPreset = getLoadedPreset(); - if (mPreset == null) { - if (loadedPreset == null) { - return false; - } else { - return loadedPreset.hasModifications(); - } - } else { - if (loadedPreset == null) { - return mPreset.hasModifications(); - } else { - return !mPreset.equals(loadedPreset); - } - } - } - - public SharedBuffer getPreviewBuffer() { - return mPreviewBuffer; - } - - public SharedPreset getPreviewPreset() { - return mPreviewPreset; - } - - public Bitmap getFilteredImage() { - mPreviewBuffer.swapConsumerIfNeeded(); // get latest bitmap - Buffer consumer = mPreviewBuffer.getConsumer(); - if (consumer != null) { - return consumer.getBitmap(); - } - return null; - } - - public Bitmap getFiltersOnlyImage() { - return mFiltersOnlyBitmap; - } - - public Bitmap getGeometryOnlyImage() { - return mGeometryOnlyBitmap; - } - - public Bitmap getPartialImage() { - return mPartialBitmap; - } - - public Bitmap getHighresImage() { - return mHighresBitmap; - } - - public void notifyObservers() { - for (ImageShow observer : mObservers) { - observer.invalidate(); - } - } - - public void updatePresets(boolean force) { - if (force || mGeometryOnlyPreset == null) { - ImagePreset newPreset = new ImagePreset(mPreset); - newPreset.setDoApplyFilters(false); - newPreset.setDoApplyGeometry(true); - if (force || mGeometryOnlyPreset == null - || !newPreset.same(mGeometryOnlyPreset)) { - mGeometryOnlyPreset = newPreset; - RenderingRequest.post(mActivity, getOriginalBitmapLarge(), - mGeometryOnlyPreset, RenderingRequest.GEOMETRY_RENDERING, this); - } - } - if (force || mFiltersOnlyPreset == null) { - ImagePreset newPreset = new ImagePreset(mPreset); - newPreset.setDoApplyFilters(true); - newPreset.setDoApplyGeometry(false); - if (force || mFiltersOnlyPreset == null - || !newPreset.same(mFiltersOnlyPreset)) { - mFiltersOnlyPreset = newPreset; - RenderingRequest.post(mActivity, MasterImage.getImage().getOriginalBitmapLarge(), - mFiltersOnlyPreset, RenderingRequest.FILTERS_RENDERING, this); - } - } - invalidatePreview(); - } - - public FilterRepresentation getCurrentFilterRepresentation() { - return mCurrentFilterRepresentation; - } - - public void setCurrentFilterRepresentation(FilterRepresentation currentFilterRepresentation) { - mCurrentFilterRepresentation = currentFilterRepresentation; - } - - public void invalidateFiltersOnly() { - mFiltersOnlyPreset = null; - updatePresets(false); - } - - public void invalidatePartialPreview() { - if (mPartialBitmap != null) { - mPartialBitmap = null; - notifyObservers(); - } - } - - public void invalidateHighresPreview() { - if (mHighresBitmap != null) { - mHighresBitmap = null; - notifyObservers(); - } - } - - public void invalidatePreview() { - mPreviewPreset.enqueuePreset(mPreset); - mPreviewBuffer.invalidate(); - invalidatePartialPreview(); - invalidateHighresPreview(); - needsUpdatePartialPreview(); - needsUpdateHighResPreview(); - mActivity.getProcessingService().updatePreviewBuffer(); - } - - public void setImageShowSize(int w, int h) { - if (mImageShowSize.x != w || mImageShowSize.y != h) { - mImageShowSize.set(w, h); - needsUpdatePartialPreview(); - needsUpdateHighResPreview(); - } - } - - private Matrix getImageToScreenMatrix(boolean reflectRotation) { - if (getOriginalBounds() == null || mImageShowSize.x == 0 || mImageShowSize.y == 0) { - return new Matrix(); - } - Matrix m = GeometryMathUtils.getImageToScreenMatrix(mPreset.getGeometryFilters(), - reflectRotation, getOriginalBounds(), mImageShowSize.x, mImageShowSize.y); - if (m == null) { - m = new Matrix(); - m.reset(); - return m; - } - Point translate = getTranslation(); - float scaleFactor = getScaleFactor(); - m.postTranslate(translate.x, translate.y); - m.postScale(scaleFactor, scaleFactor, mImageShowSize.x / 2.0f, mImageShowSize.y / 2.0f); - return m; - } - - private Matrix getScreenToImageMatrix(boolean reflectRotation) { - Matrix m = getImageToScreenMatrix(reflectRotation); - Matrix invert = new Matrix(); - m.invert(invert); - return invert; - } - - public void needsUpdateHighResPreview() { - if (!mSupportsHighRes) { - return; - } - if (mActivity.getProcessingService() == null) { - return; - } - mActivity.getProcessingService().postHighresRenderingRequest(mPreset, - getScaleFactor(), this); - invalidateHighresPreview(); - } - - public void needsUpdatePartialPreview() { - if (mPreset == null) { - return; - } - if (!mPreset.canDoPartialRendering()) { - invalidatePartialPreview(); - return; - } - Matrix m = getScreenToImageMatrix(true); - RectF r = new RectF(0, 0, mImageShowSize.x, mImageShowSize.y); - RectF dest = new RectF(); - m.mapRect(dest, r); - Rect bounds = new Rect(); - dest.roundOut(bounds); - RenderingRequest.post(mActivity, null, mPreset, RenderingRequest.PARTIAL_RENDERING, - this, bounds, new Rect(0, 0, mImageShowSize.x, mImageShowSize.y)); - invalidatePartialPreview(); - } - - @Override - public void available(RenderingRequest request) { - if (request.getBitmap() == null) { - return; - } - - boolean needsCheckModification = false; - if (request.getType() == RenderingRequest.GEOMETRY_RENDERING) { - mGeometryOnlyBitmap = request.getBitmap(); - needsCheckModification = true; - } - if (request.getType() == RenderingRequest.FILTERS_RENDERING) { - mFiltersOnlyBitmap = request.getBitmap(); - notifyObservers(); - needsCheckModification = true; - } - if (request.getType() == RenderingRequest.PARTIAL_RENDERING - && request.getScaleFactor() == getScaleFactor()) { - mPartialBitmap = request.getBitmap(); - notifyObservers(); - needsCheckModification = true; - } - if (request.getType() == RenderingRequest.HIGHRES_RENDERING) { - mHighresBitmap = request.getBitmap(); - notifyObservers(); - needsCheckModification = true; - } - if (needsCheckModification) { - mActivity.enableSave(hasModifications()); - } - } - - public static void reset() { - sMasterImage = null; - } - - public float getScaleFactor() { - return mScaleFactor; - } - - public void setScaleFactor(float scaleFactor) { - if (DISABLEZOOM) { - return; - } - if (scaleFactor == mScaleFactor) { - return; - } - mScaleFactor = scaleFactor; - invalidatePartialPreview(); - } - - public Point getTranslation() { - return mTranslation; - } - - public void setTranslation(Point translation) { - if (DISABLEZOOM) { - mTranslation.x = 0; - mTranslation.y = 0; - return; - } - mTranslation.x = translation.x; - mTranslation.y = translation.y; - needsUpdatePartialPreview(); - } - - public Point getOriginalTranslation() { - return mOriginalTranslation; - } - - public void setOriginalTranslation(Point originalTranslation) { - if (DISABLEZOOM) { - return; - } - mOriginalTranslation.x = originalTranslation.x; - mOriginalTranslation.y = originalTranslation.y; - } - - public void resetTranslation() { - mTranslation.x = 0; - mTranslation.y = 0; - needsUpdatePartialPreview(); - } - - public Bitmap getThumbnailBitmap() { - return getOriginalBitmapSmall(); - } - - public Bitmap getLargeThumbnailBitmap() { - return getOriginalBitmapLarge(); - } - - public float getMaxScaleFactor() { - if (DISABLEZOOM) { - return 1; - } - return mMaxScaleFactor; - } - - public void setMaxScaleFactor(float maxScaleFactor) { - mMaxScaleFactor = maxScaleFactor; - } - - public boolean supportsHighRes() { - return mSupportsHighRes; - } - - public void setShowsOriginal(boolean value) { - mShowsOriginal = value; - notifyObservers(); - } - - public boolean showsOriginal() { - return mShowsOriginal; - } - - public void setLoadedPreset(ImagePreset preset) { - mLoadedPreset = preset; - } - - public ImagePreset getLoadedPreset() { - return mLoadedPreset; - } - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/Oval.java b/src/com/android/gallery3d/filtershow/imageshow/Oval.java deleted file mode 100644 index 28f278f1c..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/Oval.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.imageshow; - -public interface Oval { - void setCenter(float x, float y); - void setRadius(float w, float h); - float getCenterX(); - float getCenterY(); - float getRadiusX(); - float getRadiusY(); - void setRadiusY(float y); - void setRadiusX(float x); - -} diff --git a/src/com/android/gallery3d/filtershow/imageshow/Spline.java b/src/com/android/gallery3d/filtershow/imageshow/Spline.java deleted file mode 100644 index 3c27a4d0f..000000000 --- a/src/com/android/gallery3d/filtershow/imageshow/Spline.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * 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.imageshow; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.drawable.Drawable; -import android.util.Log; - -import java.util.Collections; -import java.util.Vector; - -public class Spline { - private final Vector<ControlPoint> mPoints; - private static Drawable mCurveHandle; - private static int mCurveHandleSize; - private static int mCurveWidth; - - public static final int RGB = 0; - public static final int RED = 1; - public static final int GREEN = 2; - public static final int BLUE = 3; - private static final String LOGTAG = "Spline"; - - private final Paint gPaint = new Paint(); - private ControlPoint mCurrentControlPoint = null; - - public Spline() { - mPoints = new Vector<ControlPoint>(); - } - - public Spline(Spline spline) { - mPoints = new Vector<ControlPoint>(); - for (int i = 0; i < spline.mPoints.size(); i++) { - ControlPoint p = spline.mPoints.elementAt(i); - ControlPoint newPoint = new ControlPoint(p); - mPoints.add(newPoint); - if (spline.mCurrentControlPoint == p) { - mCurrentControlPoint = newPoint; - } - } - Collections.sort(mPoints); - } - - public static void setCurveHandle(Drawable drawable, int size) { - mCurveHandle = drawable; - mCurveHandleSize = size; - } - - public static void setCurveWidth(int width) { - mCurveWidth = width; - } - - public static int curveHandleSize() { - return mCurveHandleSize; - } - - public static int colorForCurve(int curveIndex) { - switch (curveIndex) { - case Spline.RED: - return Color.RED; - case GREEN: - return Color.GREEN; - case BLUE: - return Color.BLUE; - } - return Color.WHITE; - } - - public boolean sameValues(Spline other) { - if (this == other) { - return true; - } - if (other == null) { - return false; - } - - if (getNbPoints() != other.getNbPoints()) { - return false; - } - - for (int i = 0; i < getNbPoints(); i++) { - ControlPoint p = mPoints.elementAt(i); - ControlPoint otherPoint = other.mPoints.elementAt(i); - if (!p.sameValues(otherPoint)) { - return false; - } - } - return true; - } - - private void didMovePoint(ControlPoint point) { - mCurrentControlPoint = point; - } - - public void movePoint(int pick, float x, float y) { - if (pick < 0 || pick > mPoints.size() - 1) { - return; - } - ControlPoint point = mPoints.elementAt(pick); - point.x = x; - point.y = y; - didMovePoint(point); - } - - public boolean isOriginal() { - if (this.getNbPoints() != 2) { - return false; - } - if (mPoints.elementAt(0).x != 0 || mPoints.elementAt(0).y != 1) { - return false; - } - if (mPoints.elementAt(1).x != 1 || mPoints.elementAt(1).y != 0) { - return false; - } - return true; - } - - public void reset() { - mPoints.clear(); - addPoint(0.0f, 1.0f); - addPoint(1.0f, 0.0f); - } - - private void drawHandles(Canvas canvas, Drawable indicator, float centerX, float centerY) { - int left = (int) centerX - mCurveHandleSize / 2; - int top = (int) centerY - mCurveHandleSize / 2; - indicator.setBounds(left, top, left + mCurveHandleSize, top + mCurveHandleSize); - indicator.draw(canvas); - } - - public float[] getAppliedCurve() { - float[] curve = new float[256]; - ControlPoint[] points = new ControlPoint[mPoints.size()]; - for (int i = 0; i < mPoints.size(); i++) { - ControlPoint p = mPoints.get(i); - points[i] = new ControlPoint(p.x, p.y); - } - double[] derivatives = solveSystem(points); - int start = 0; - int end = 256; - if (points[0].x != 0) { - start = (int) (points[0].x * 256); - } - if (points[points.length - 1].x != 1) { - end = (int) (points[points.length - 1].x * 256); - } - for (int i = 0; i < start; i++) { - curve[i] = 1.0f - points[0].y; - } - for (int i = end; i < 256; i++) { - curve[i] = 1.0f - points[points.length - 1].y; - } - for (int i = start; i < end; i++) { - ControlPoint cur = null; - ControlPoint next = null; - double x = i / 256.0; - int pivot = 0; - for (int j = 0; j < points.length - 1; j++) { - if (x >= points[j].x && x <= points[j + 1].x) { - pivot = j; - } - } - cur = points[pivot]; - next = points[pivot + 1]; - if (x <= next.x) { - double x1 = cur.x; - double x2 = next.x; - double y1 = cur.y; - double y2 = next.y; - - // Use the second derivatives to apply the cubic spline - // equation: - double delta = (x2 - x1); - double delta2 = delta * delta; - double b = (x - x1) / delta; - double a = 1 - b; - double ta = a * y1; - double tb = b * y2; - double tc = (a * a * a - a) * derivatives[pivot]; - double td = (b * b * b - b) * derivatives[pivot + 1]; - double y = ta + tb + (delta2 / 6) * (tc + td); - if (y > 1.0f) { - y = 1.0f; - } - if (y < 0) { - y = 0; - } - curve[i] = (float) (1.0f - y); - } else { - curve[i] = 1.0f - next.y; - } - } - return curve; - } - - private void drawGrid(Canvas canvas, float w, float h) { - // Grid - gPaint.setARGB(128, 150, 150, 150); - gPaint.setStrokeWidth(1); - - float stepH = h / 9; - float stepW = w / 9; - - // central diagonal - gPaint.setARGB(255, 100, 100, 100); - gPaint.setStrokeWidth(2); - canvas.drawLine(0, h, w, 0, gPaint); - - gPaint.setARGB(128, 200, 200, 200); - gPaint.setStrokeWidth(4); - stepH = h / 3; - stepW = w / 3; - for (int j = 1; j < 3; j++) { - canvas.drawLine(0, j * stepH, w, j * stepH, gPaint); - canvas.drawLine(j * stepW, 0, j * stepW, h, gPaint); - } - canvas.drawLine(0, 0, 0, h, gPaint); - canvas.drawLine(w, 0, w, h, gPaint); - canvas.drawLine(0, 0, w, 0, gPaint); - canvas.drawLine(0, h, w, h, gPaint); - } - - public void draw(Canvas canvas, int color, int canvasWidth, int canvasHeight, - boolean showHandles, boolean moving) { - float w = canvasWidth - mCurveHandleSize; - float h = canvasHeight - mCurveHandleSize; - float dx = mCurveHandleSize / 2; - float dy = mCurveHandleSize / 2; - - // The cubic spline equation is (from numerical recipes in C): - // y = a(y_i) + b(y_i+1) + c(y"_i) + d(y"_i+1) - // - // with c(y"_i) and d(y"_i+1): - // c(y"_i) = 1/6 (a^3 - a) delta^2 (y"_i) - // d(y"_i_+1) = 1/6 (b^3 - b) delta^2 (y"_i+1) - // - // and delta: - // delta = x_i+1 - x_i - // - // To find the second derivatives y", we can rearrange the equation as: - // A(y"_i-1) + B(y"_i) + C(y"_i+1) = D - // - // With the coefficients A, B, C, D: - // A = 1/6 (x_i - x_i-1) - // B = 1/3 (x_i+1 - x_i-1) - // C = 1/6 (x_i+1 - x_i) - // D = (y_i+1 - y_i)/(x_i+1 - x_i) - (y_i - y_i-1)/(x_i - x_i-1) - // - // We can now easily solve the equation to find the second derivatives: - ControlPoint[] points = new ControlPoint[mPoints.size()]; - for (int i = 0; i < mPoints.size(); i++) { - ControlPoint p = mPoints.get(i); - points[i] = new ControlPoint(p.x * w, p.y * h); - } - double[] derivatives = solveSystem(points); - - Path path = new Path(); - path.moveTo(0, points[0].y); - for (int i = 0; i < points.length - 1; i++) { - double x1 = points[i].x; - double x2 = points[i + 1].x; - double y1 = points[i].y; - double y2 = points[i + 1].y; - - for (double x = x1; x < x2; x += 20) { - // Use the second derivatives to apply the cubic spline - // equation: - double delta = (x2 - x1); - double delta2 = delta * delta; - double b = (x - x1) / delta; - double a = 1 - b; - double ta = a * y1; - double tb = b * y2; - double tc = (a * a * a - a) * derivatives[i]; - double td = (b * b * b - b) * derivatives[i + 1]; - double y = ta + tb + (delta2 / 6) * (tc + td); - if (y > h) { - y = h; - } - if (y < 0) { - y = 0; - } - path.lineTo((float) x, (float) y); - } - } - canvas.save(); - canvas.translate(dx, dy); - drawGrid(canvas, w, h); - ControlPoint lastPoint = points[points.length - 1]; - path.lineTo(lastPoint.x, lastPoint.y); - path.lineTo(w, lastPoint.y); - Paint paint = new Paint(); - paint.setAntiAlias(true); - paint.setFilterBitmap(true); - paint.setDither(true); - paint.setStyle(Paint.Style.STROKE); - int curveWidth = mCurveWidth; - if (showHandles) { - curveWidth *= 1.5; - } - paint.setStrokeWidth(curveWidth + 2); - paint.setColor(Color.BLACK); - canvas.drawPath(path, paint); - - if (moving && mCurrentControlPoint != null) { - float px = mCurrentControlPoint.x * w; - float py = mCurrentControlPoint.y * h; - paint.setStrokeWidth(3); - paint.setColor(Color.BLACK); - canvas.drawLine(px, py, px, h, paint); - canvas.drawLine(0, py, px, py, paint); - paint.setStrokeWidth(1); - paint.setColor(color); - canvas.drawLine(px, py, px, h, paint); - canvas.drawLine(0, py, px, py, paint); - } - - paint.setStrokeWidth(curveWidth); - paint.setColor(color); - canvas.drawPath(path, paint); - if (showHandles) { - for (int i = 0; i < points.length; i++) { - float x = points[i].x; - float y = points[i].y; - drawHandles(canvas, mCurveHandle, x, y); - } - } - canvas.restore(); - } - - double[] solveSystem(ControlPoint[] points) { - int n = points.length; - double[][] system = new double[n][3]; - double[] result = new double[n]; // d - double[] solution = new double[n]; // returned coefficients - system[0][1] = 1; - system[n - 1][1] = 1; - double d6 = 1.0 / 6.0; - double d3 = 1.0 / 3.0; - - // let's create a tridiagonal matrix representing the - // system, and apply the TDMA algorithm to solve it - // (see http://en.wikipedia.org/wiki/Tridiagonal_matrix_algorithm) - for (int i = 1; i < n - 1; i++) { - double deltaPrevX = points[i].x - points[i - 1].x; - double deltaX = points[i + 1].x - points[i - 1].x; - double deltaNextX = points[i + 1].x - points[i].x; - double deltaNextY = points[i + 1].y - points[i].y; - double deltaPrevY = points[i].y - points[i - 1].y; - system[i][0] = d6 * deltaPrevX; // a_i - system[i][1] = d3 * deltaX; // b_i - system[i][2] = d6 * deltaNextX; // c_i - result[i] = (deltaNextY / deltaNextX) - (deltaPrevY / deltaPrevX); // d_i - } - - // Forward sweep - for (int i = 1; i < n; i++) { - // m = a_i/b_i-1 - double m = system[i][0] / system[i - 1][1]; - // b_i = b_i - m(c_i-1) - system[i][1] = system[i][1] - m * system[i - 1][2]; - // d_i = d_i - m(d_i-1) - result[i] = result[i] - m * result[i - 1]; - } - - // Back substitution - solution[n - 1] = result[n - 1] / system[n - 1][1]; - for (int i = n - 2; i >= 0; --i) { - solution[i] = (result[i] - system[i][2] * solution[i + 1]) / system[i][1]; - } - return solution; - } - - public int addPoint(float x, float y) { - return addPoint(new ControlPoint(x, y)); - } - - public int addPoint(ControlPoint v) { - mPoints.add(v); - Collections.sort(mPoints); - return mPoints.indexOf(v); - } - - public void deletePoint(int n) { - mPoints.remove(n); - if (mPoints.size() < 2) { - reset(); - } - Collections.sort(mPoints); - } - - public int getNbPoints() { - return mPoints.size(); - } - - public ControlPoint getPoint(int n) { - return mPoints.elementAt(n); - } - - public boolean isPointContained(float x, int n) { - for (int i = 0; i < n; i++) { - ControlPoint point = mPoints.elementAt(i); - if (point.x > x) { - return false; - } - } - for (int i = n + 1; i < mPoints.size(); i++) { - ControlPoint point = mPoints.elementAt(i); - if (point.x < x) { - return false; - } - } - return true; - } - - public Spline copy() { - Spline spline = new Spline(); - for (int i = 0; i < mPoints.size(); i++) { - ControlPoint point = mPoints.elementAt(i); - spline.addPoint(point.copy()); - } - return spline; - } - - public void show() { - Log.v(LOGTAG, "show curve " + this); - for (int i = 0; i < mPoints.size(); i++) { - ControlPoint point = mPoints.elementAt(i); - Log.v(LOGTAG, "point " + i + " is (" + point.x + ", " + point.y + ")"); - } - } - -} |