diff options
18 files changed, 673 insertions, 0 deletions
diff --git a/res/drawable-hdpi/filtershow_button_grad.png b/res/drawable-hdpi/filtershow_button_grad.png Binary files differnew file mode 100644 index 000000000..01a565d1d --- /dev/null +++ b/res/drawable-hdpi/filtershow_button_grad.png diff --git a/res/drawable-hdpi/ic_grad_add.png b/res/drawable-hdpi/ic_grad_add.png Binary files differnew file mode 100644 index 000000000..4e0dc2b7b --- /dev/null +++ b/res/drawable-hdpi/ic_grad_add.png diff --git a/res/drawable-hdpi/ic_grad_del.png b/res/drawable-hdpi/ic_grad_del.png Binary files differnew file mode 100644 index 000000000..521541f49 --- /dev/null +++ b/res/drawable-hdpi/ic_grad_del.png diff --git a/res/drawable-mdpi/filtershow_button_grad.png b/res/drawable-mdpi/filtershow_button_grad.png Binary files differnew file mode 100644 index 000000000..f04af799e --- /dev/null +++ b/res/drawable-mdpi/filtershow_button_grad.png diff --git a/res/drawable-mdpi/ic_grad_add.png b/res/drawable-mdpi/ic_grad_add.png Binary files differnew file mode 100644 index 000000000..94657346e --- /dev/null +++ b/res/drawable-mdpi/ic_grad_add.png diff --git a/res/drawable-mdpi/ic_grad_del.png b/res/drawable-mdpi/ic_grad_del.png Binary files differnew file mode 100644 index 000000000..b6221e608 --- /dev/null +++ b/res/drawable-mdpi/ic_grad_del.png diff --git a/res/drawable-xhdpi/filtershow_button_grad.png b/res/drawable-xhdpi/filtershow_button_grad.png Binary files differnew file mode 100644 index 000000000..3feeef69e --- /dev/null +++ b/res/drawable-xhdpi/filtershow_button_grad.png diff --git a/res/drawable-xhdpi/ic_grad_add.png b/res/drawable-xhdpi/ic_grad_add.png Binary files differnew file mode 100644 index 000000000..ca7b654b3 --- /dev/null +++ b/res/drawable-xhdpi/ic_grad_add.png diff --git a/res/drawable-xhdpi/ic_grad_del.png b/res/drawable-xhdpi/ic_grad_del.png Binary files differnew file mode 100644 index 000000000..9dfb392c8 --- /dev/null +++ b/res/drawable-xhdpi/ic_grad_del.png diff --git a/res/drawable/filtershow_grad_button.xml b/res/drawable/filtershow_grad_button.xml new file mode 100644 index 000000000..4bf84c1e6 --- /dev/null +++ b/res/drawable/filtershow_grad_button.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + + <item android:state_checked="false" android:drawable="@android:color/transparent" /> + <item android:state_checked="true" android:drawable="@android:color/holo_blue_light" /> + +</selector>
\ No newline at end of file diff --git a/res/layout/editor_grad_button.xml b/res/layout/editor_grad_button.xml new file mode 100644 index 000000000..4d1b10b6b --- /dev/null +++ b/res/layout/editor_grad_button.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_alignParentTop="true" + android:layout_marginLeft="26dp" + android:layout_marginTop="21dp" + android:orientation="horizontal" > + + <com.android.gallery3d.filtershow.ui.FramedTextButton + android:id="@+id/editorGradButton" + android:layout_width="84dip" + android:layout_height="84dip" + android:layout_gravity="center_vertical|left" + android:background="@drawable/filtershow_button_background" + android:scaleType="centerInside" + android:visibility="visible" + android:text="@string/editor_grad_style" /> + + <ToggleButton + android:id="@+id/editor_grad_new" + android:layout_width="84dip" + android:layout_height="84dip" + android:layout_gravity="center_vertical|left" + android:background="@drawable/filtershow_grad_button" + android:scaleType="centerInside" + android:visibility="visible" + android:textOff="@string/editor_grad_new" + android:textOn="@string/editor_grad_new" /> + +</LinearLayout>
\ No newline at end of file diff --git a/res/layout/filtershow_grad_editor.xml b/res/layout/filtershow_grad_editor.xml new file mode 100644 index 000000000..6c4721e62 --- /dev/null +++ b/res/layout/filtershow_grad_editor.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> + +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/gradEditor" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" > + + <com.android.gallery3d.filtershow.imageshow.ImageGrad + android:id="@+id/imageShow" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + + </FrameLayout>
\ No newline at end of file diff --git a/res/menu/filtershow_menu_grad.xml b/res/menu/filtershow_menu_grad.xml new file mode 100644 index 000000000..1dee7e0b4 --- /dev/null +++ b/res/menu/filtershow_menu_grad.xml @@ -0,0 +1,27 @@ +<!-- + 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. +--> + +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + <item + android:id="@+id/editor_grad_brightness" + android:title="@string/editor_grad_brightness"/> + <item + android:id="@+id/editor_grad_saturation" + android:title="@string/editor_grad_saturation"/> + <item + android:id="@+id/editor_grad_contrast" + android:title="@string/editor_grad_contrast"/> +</menu> diff --git a/res/values/filtershow_color.xml b/res/values/filtershow_color.xml index 927bfa276..d7cf79d70 100644 --- a/res/values/filtershow_color.xml +++ b/res/values/filtershow_color.xml @@ -38,4 +38,14 @@ <color name="filtershow_categoryview_background">#1a1a1a</color> <color name="filtershow_categoryview_text">#a7a7a7</color> <color name="filtershow_category_selection">#ffffffff</color> + <color name="gradcontrol_point_center">#ffffffff</color> + <color name="gradcontrol_point_edge">#ffffffff</color> + <color name="gradcontrol_graypoint_center">#888888</color> + <color name="gradcontrol_graypoint_edge">#BBBBBB</color> + <color name="gradcontrol_point_shadow_start">#66000000</color> + <color name="gradcontrol_point_shadow_end">#00000000</color> + <color name="gradcontrol_line_color">#FFFFFF</color> + <color name="gradcontrol_line_shadow">#000000</color> + + </resources>
\ No newline at end of file diff --git a/res/values/filtershow_ids.xml b/res/values/filtershow_ids.xml index 8ac294136..e57a0d559 100644 --- a/res/values/filtershow_ids.xml +++ b/res/values/filtershow_ids.xml @@ -47,4 +47,5 @@ <item type="id" name="editorRotate" /> <item type="id" name="editorStraighten" /> <item type="id" name="editorParametric" /> + <item type="id" name="editorGrad" /> </resources> diff --git a/res/values/filtershow_strings.xml b/res/values/filtershow_strings.xml index 503ebbb34..a5c3dc8c4 100644 --- a/res/values/filtershow_strings.xml +++ b/res/values/filtershow_strings.xml @@ -160,6 +160,20 @@ <string name="kmeans">Warhol</string> <!-- Label for the image downsampling effect (makes image smaller) [CHAR LIMIT=15] --> <string name="downsample">Downsample</string> + <!-- Label for the image graduated filter effect [CHAR LIMIT=15] --> + <string name="grad">Graduated</string> + <!-- Label for the Brightness effect [CHAR LIMIT=20] --> + <string name="editor_grad_brightness">Brightness</string> + <!-- Label for the Contrast filter effect [CHAR LIMIT=20] --> + <string name="editor_grad_contrast">Contrast</string> + <!-- Label for the saturation effect [CHAR LIMIT=20] --> + <string name="editor_grad_saturation">Saturation</string> + + <!-- Label for the image graduated filter effect [CHAR LIMIT=20] --> + <string name="editor_grad_style">Style</string> + <!-- Label for the image new grad layer [CHAR LIMIT=20] --> + <string name="editor_grad_new">new</string> + <!-- Labels for the curves tool --> diff --git a/res/values/filtershow_values.xml b/res/values/filtershow_values.xml index ac81e6a26..bd1f8904e 100644 --- a/res/values/filtershow_values.xml +++ b/res/values/filtershow_values.xml @@ -33,4 +33,11 @@ <!-- Category Panel Text Size --> <dimen name="category_panel_margin">4dip</dimen> + <!-- Grad filter dot size --> + <dimen name="gradcontrol_dot_size">20dip</dimen> + + <!-- Grad filter minimum touch distance --> + <dimen name="gradcontrol_min_touch_dist">40dip</dimen> + + </resources>
\ No newline at end of file diff --git a/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java b/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java new file mode 100644 index 000000000..1bfce6f05 --- /dev/null +++ b/src/com/android/gallery3d/filtershow/filters/FilterGradRepresentation.java @@ -0,0 +1,514 @@ +/* + * 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.filters; + +import android.graphics.Rect; +import android.util.JsonReader; +import android.util.JsonWriter; + +import com.android.gallery3d.R; +import com.android.gallery3d.filtershow.editors.EditorGrad; +import com.android.gallery3d.filtershow.imageshow.MasterImage; +import com.android.gallery3d.filtershow.imageshow.Line; + +import java.io.IOException; +import java.util.Vector; + +public class FilterGradRepresentation extends FilterRepresentation + implements Line { + private static final String LOGTAG = "FilterGradRepresentation"; + public static final int MAX_POINTS = 16; + public static final int PARAM_BRIGHTNESS = 0; + public static final int PARAM_SATURATION = 1; + public static final int PARAM_CONTRAST = 2; + private static final double ADD_MIN_DIST = .05; + private static String LINE_NAME = "Point"; + private static final String SERIALIZATION_NAME = "grad"; + + public FilterGradRepresentation() { + super("Grad"); + setSerializationName(SERIALIZATION_NAME); + creatExample(); + setOverlayId(R.drawable.filtershow_button_colors_vignette); + setFilterClass(ImageFilterGrad.class); + setTextId(R.string.grad); + setEditorId(EditorGrad.ID); + } + + public void trimVector(){ + int n = mBands.size(); + for (int i = n; i < MAX_POINTS; i++) { + mBands.add(new Band()); + } + for (int i = MAX_POINTS; i < n; i++) { + mBands.remove(i); + } + } + + Vector<Band> mBands = new Vector<Band>(); + Band mCurrentBand; + + static class Band { + private boolean mask = true; + private boolean active = true; + private int xPos1 = -1; + private int yPos1 = 100; + private int xPos2 = -1; + private int yPos2 = 100; + private int brightness = 40; + private int contrast = 0; + private int saturation = 0; + private boolean inking; + + public Band() { + } + + public Band(int x, int y) { + xPos1 = x; + yPos1 = y+30; + xPos2 = x; + yPos2 = y-30; + } + + public Band(Band copy) { + mask = copy.mask; + active = copy.active; + xPos1 = copy.xPos1; + yPos1 = copy.yPos1; + xPos2 = copy.xPos2; + yPos2 = copy.yPos2; + brightness = copy.brightness; + contrast = copy.contrast; + saturation = copy.saturation; + inking = copy.inking; + } + + } + + @Override + public String toString() { + int count = 0; + for (Band point : mBands) { + if (!point.mask) { + count++; + } + } + return "c=" + mBands.indexOf(mBands) + "[" + mBands.size() + "]" + count; + } + + private void creatExample() { + Band p = new Band(); + p.mask = false; + p.active = true; + p.xPos1 = -1; + p.yPos1 = 100; + p.xPos2 = -1; + p.yPos2 = 100; + p.brightness = 40; + p.contrast = 0; + p.saturation = 0; + p.inking = false; + mBands.add(0, p); + mCurrentBand = p; + trimVector(); + } + + @Override + public void useParametersFrom(FilterRepresentation a) { + FilterGradRepresentation rep = (FilterGradRepresentation) a; + Vector<Band> tmpBands = new Vector<Band>(); + int n = (rep.mCurrentBand == null) ? 0 : rep.mBands.indexOf(rep.mCurrentBand); + for (Band band : rep.mBands) { + tmpBands.add(new Band(band)); + } + mCurrentBand = null; + mBands = tmpBands; + mCurrentBand = mBands.elementAt(n); + } + + @Override + public FilterRepresentation copy() { + FilterGradRepresentation representation = new FilterGradRepresentation(); + copyAllParameters(representation); + return representation; + } + + @Override + protected void copyAllParameters(FilterRepresentation representation) { + super.copyAllParameters(representation); + representation.useParametersFrom(this); + } + + @Override + public boolean equals(FilterRepresentation representation) { + if (representation instanceof FilterGradRepresentation) { + return true; // TODO much more extensive equals needed + } + return false; + } + + public int getNumberOfBands() { + int count = 0; + for (Band point : mBands) { + if (!point.mask) { + count++; + } + } + return count; + } + + public void toggleInking() { + mCurrentBand.inking = !mCurrentBand.inking; + } + + public void setInking(boolean on) { + for (Band point : mBands) { + point.inking = false; + } + mCurrentBand.inking = on; + } + + public int addBand(Rect rect) { + mBands.add(0, mCurrentBand = new Band(rect.centerX(), rect.centerY())); + mCurrentBand.mask = false; + int x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2; + int y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2; + double addDelta = ADD_MIN_DIST * Math.max(rect.width(), rect.height()); + boolean moved = true; + int count = 0; + int toMove = mBands.indexOf(mCurrentBand); + + while (moved) { + moved = false; + count++; + if (count > 14) { + break; + } + + for (Band point : mBands) { + if (point.mask) { + break; + } + } + + for (Band point : mBands) { + if (point.mask) { + break; + } + int index = mBands.indexOf(point); + + if (toMove != index) { + double dist = Math.hypot(point.xPos1 - x, point.yPos1 - y); + if (dist < addDelta) { + moved = true; + mCurrentBand.xPos1 += addDelta; + mCurrentBand.yPos1 += addDelta; + mCurrentBand.xPos2 += addDelta; + mCurrentBand.yPos2 += addDelta; + x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2; + y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2; + + if (mCurrentBand.yPos1 > rect.bottom) { + mCurrentBand.yPos1 = (int) (rect.top + addDelta); + } + if (mCurrentBand.xPos1 > rect.right) { + mCurrentBand.xPos1 = (int) (rect.left + addDelta); + } + } + } + } + } + trimVector(); + return 0; + } + + public void deleteCurrentBand() { + int index = mBands.indexOf(mCurrentBand); + mBands.remove(mCurrentBand); + trimVector(); + if (getNumberOfBands() == 0) { + addBand(MasterImage.getImage().getOriginalBounds()); + } + mCurrentBand = mBands.get(0); + } + + public void nextPoint(){ + int index = mBands.indexOf(mCurrentBand); + int tmp = index; + Band point; + int k = 0; + do { + index = (index+1)% mBands.size(); + point = mBands.get(index); + if (k++ >= mBands.size()) { + break; + } + } + while (point.mask == true); + mCurrentBand = mBands.get(index); + } + + public void setSelectedPoint(int pos) { + mCurrentBand = mBands.get(pos); + } + + public int getSelectedPoint() { + return mBands.indexOf(mCurrentBand); + } + + public boolean[] getMask() { + boolean[] ret = new boolean[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = !point.mask; + } + return ret; + } + + public boolean[] getActive() { + boolean[] ret = new boolean[mBands.size()]; + int i = 0; + String s = ""; + for (Band point : mBands) { + ret[i++] = point.active; + s += (point.active) ? "1" : "0"; + } + return ret; + } + + public int[] getXPos1() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.xPos1; + } + return ret; + } + + public int[] getYPos1() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.yPos1; + } + return ret; + } + + public int[] getXPos2() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.xPos2; + } + return ret; + } + + public int[] getYPos2() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.yPos2; + } + return ret; + } + + public int[] getBrightness() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.brightness; + } + return ret; + } + + public int[] getContrast() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.contrast; + } + return ret; + } + + public int[] getSaturation() { + int[] ret = new int[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.saturation; + } + return ret; + } + + public boolean[] getInking() { + boolean[] ret = new boolean[mBands.size()]; + int i = 0; + for (Band point : mBands) { + ret[i++] = point.inking; + } + return ret; + } + + public int getParameter(int type) { + switch (type){ + case PARAM_BRIGHTNESS: + return mCurrentBand.brightness; + case PARAM_SATURATION: + return mCurrentBand.saturation; + case PARAM_CONTRAST: + return mCurrentBand.contrast; + } + throw new IllegalArgumentException("no such type " + type); + } + + public int getParameterMax(int type) { + switch (type) { + case PARAM_BRIGHTNESS: + return 100; + case PARAM_SATURATION: + return 100; + case PARAM_CONTRAST: + return 100; + } + throw new IllegalArgumentException("no such type " + type); + } + + public int getParameterMin(int type) { + switch (type) { + case PARAM_BRIGHTNESS: + return -100; + case PARAM_SATURATION: + return -100; + case PARAM_CONTRAST: + return -100; + } + throw new IllegalArgumentException("no such type " + type); + } + + public void setParameter(int type, int value) { + mCurrentBand.mask = false; + switch (type) { + case PARAM_BRIGHTNESS: + mCurrentBand.brightness = value; + break; + case PARAM_SATURATION: + mCurrentBand.saturation = value; + break; + case PARAM_CONTRAST: + mCurrentBand.contrast = value; + break; + default: + throw new IllegalArgumentException("no such type " + type); + } + } + + @Override + public void setPoint1(float x, float y) { + mCurrentBand.xPos1 = (int)x; + mCurrentBand.yPos1 = (int)y; + } + + @Override + public void setPoint2(float x, float y) { + mCurrentBand.xPos2 = (int)x; + mCurrentBand.yPos2 = (int)y; + } + + @Override + public float getPoint1X() { + return mCurrentBand.xPos1; + } + + @Override + public float getPoint1Y() { + return mCurrentBand.yPos1; + } + + @Override + public float getPoint2X() { + return mCurrentBand.xPos2; + } + + @Override + public float getPoint2Y() { + return mCurrentBand.yPos2; + } + + @Override + public void serializeRepresentation(JsonWriter writer) throws IOException { + writer.beginObject(); + int len = mBands.size(); + int count = 0; + + for (int i = 0; i < len; i++) { + Band point = mBands.get(i); + if (point.mask) { + continue; + } + writer.name(LINE_NAME + count); + count++; + writer.beginArray(); + writer.value(point.xPos1); + writer.value(point.yPos1); + writer.value(point.xPos2); + writer.value(point.yPos2); + writer.value(point.brightness); + writer.value(point.contrast); + writer.value(point.saturation); + writer.endArray(); + } + writer.endObject(); + } + + @Override + public void deSerializeRepresentation(JsonReader sreader) throws IOException { + sreader.beginObject(); + Vector<Band> points = new Vector<Band>(); + + while (sreader.hasNext()) { + String name = sreader.nextName(); + if (name.startsWith(LINE_NAME)) { + int pointNo = Integer.parseInt(name.substring(LINE_NAME.length())); + sreader.beginArray(); + Band p = new Band(); + p.mask = false; + sreader.hasNext(); + p.xPos1 = sreader.nextInt(); + sreader.hasNext(); + p.yPos1 = sreader.nextInt(); + sreader.hasNext(); + p.xPos2 = sreader.nextInt(); + sreader.hasNext(); + p.yPos2 = sreader.nextInt(); + sreader.hasNext(); + p.brightness = sreader.nextInt(); + sreader.hasNext(); + p.contrast = sreader.nextInt(); + sreader.hasNext(); + p.saturation = sreader.nextInt(); + sreader.hasNext(); + sreader.endArray(); + points.add(p); + + } else { + sreader.skipValue(); + } + } + mBands = points; + trimVector(); + mCurrentBand = mBands.get(0); + sreader.endObject(); + } +} |