1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.gallery3d.filtershow.filters;
17 
18 import android.content.Context;
19 import android.content.res.Resources;
20 import android.graphics.Color;
21 import android.util.Log;
22 
23 import com.android.gallery3d.R;
24 import com.android.gallery3d.filtershow.pipeline.ImagePreset;
25 
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.Vector;
29 
30 public abstract class BaseFiltersManager implements FiltersManagerInterface {
31     protected HashMap<Class, ImageFilter> mFilters = null;
32     protected HashMap<String, FilterRepresentation> mRepresentationLookup = null;
33     private static final String LOGTAG = "BaseFiltersManager";
34 
35     protected ArrayList<FilterRepresentation> mLooks = new ArrayList<FilterRepresentation>();
36     protected ArrayList<FilterRepresentation> mBorders = new ArrayList<FilterRepresentation>();
37     protected ArrayList<FilterRepresentation> mTools = new ArrayList<FilterRepresentation>();
38     protected ArrayList<FilterRepresentation> mEffects = new ArrayList<FilterRepresentation>();
39     private static int mImageBorderSize = 4; // in percent
40 
init()41     protected void init() {
42         mFilters = new HashMap<Class, ImageFilter>();
43         mRepresentationLookup = new HashMap<String, FilterRepresentation>();
44         Vector<Class> filters = new Vector<Class>();
45         addFilterClasses(filters);
46         for (Class filterClass : filters) {
47             try {
48                 Object filterInstance = filterClass.newInstance();
49                 if (filterInstance instanceof ImageFilter) {
50                     mFilters.put(filterClass, (ImageFilter) filterInstance);
51 
52                     FilterRepresentation rep =
53                         ((ImageFilter) filterInstance).getDefaultRepresentation();
54                     if (rep != null) {
55                         addRepresentation(rep);
56                     }
57                 }
58             } catch (InstantiationException e) {
59                 e.printStackTrace();
60             } catch (IllegalAccessException e) {
61                 e.printStackTrace();
62             }
63         }
64     }
65 
addRepresentation(FilterRepresentation rep)66     public void addRepresentation(FilterRepresentation rep) {
67         mRepresentationLookup.put(rep.getSerializationName(), rep);
68     }
69 
createFilterFromName(String name)70     public FilterRepresentation createFilterFromName(String name) {
71         try {
72             return mRepresentationLookup.get(name).copy();
73         } catch (Exception e) {
74             Log.v(LOGTAG, "unable to generate a filter representation for \"" + name + "\"");
75             e.printStackTrace();
76         }
77         return null;
78     }
79 
getFilter(Class c)80     public ImageFilter getFilter(Class c) {
81         return mFilters.get(c);
82     }
83 
84     @Override
getFilterForRepresentation(FilterRepresentation representation)85     public ImageFilter getFilterForRepresentation(FilterRepresentation representation) {
86         return mFilters.get(representation.getFilterClass());
87     }
88 
getRepresentation(Class c)89     public FilterRepresentation getRepresentation(Class c) {
90         ImageFilter filter = mFilters.get(c);
91         if (filter != null) {
92             return filter.getDefaultRepresentation();
93         }
94         return null;
95     }
96 
freeFilterResources(ImagePreset preset)97     public void freeFilterResources(ImagePreset preset) {
98         if (preset == null) {
99             return;
100         }
101         Vector<ImageFilter> usedFilters = preset.getUsedFilters(this);
102         for (Class c : mFilters.keySet()) {
103             ImageFilter filter = mFilters.get(c);
104             if (!usedFilters.contains(filter)) {
105                 filter.freeResources();
106             }
107         }
108     }
109 
addFilterClasses(Vector<Class> filters)110     protected void addFilterClasses(Vector<Class> filters) {
111         filters.add(ImageFilterTinyPlanet.class);
112         filters.add(ImageFilterRedEye.class);
113         filters.add(ImageFilterWBalance.class);
114         filters.add(ImageFilterExposure.class);
115         filters.add(ImageFilterContrast.class);
116         filters.add(ImageFilterShadows.class);
117         filters.add(ImageFilterHighlights.class);
118         filters.add(ImageFilterVibrance.class);
119         filters.add(ImageFilterCurves.class);
120         filters.add(ImageFilterDraw.class);
121         filters.add(ImageFilterHue.class);
122         filters.add(ImageFilterSaturated.class);
123         filters.add(ImageFilterBwFilter.class);
124         filters.add(ImageFilterNegative.class);
125         filters.add(ImageFilterEdge.class);
126         filters.add(ImageFilterKMeans.class);
127         filters.add(ImageFilterFx.class);
128         filters.add(ImageFilterBorder.class);
129         filters.add(ImageFilterColorBorder.class);
130     }
131 
getLooks()132     public ArrayList<FilterRepresentation> getLooks() {
133         return mLooks;
134     }
135 
getBorders()136     public ArrayList<FilterRepresentation> getBorders() {
137         return mBorders;
138     }
139 
getTools()140     public ArrayList<FilterRepresentation> getTools() {
141         return mTools;
142     }
143 
getEffects()144     public ArrayList<FilterRepresentation> getEffects() {
145         return mEffects;
146     }
147 
addBorders(Context context)148     public void addBorders(Context context) {
149 
150         // Do not localize
151         String[] serializationNames = {
152                 "FRAME_4X5",
153                 "FRAME_BRUSH",
154                 "FRAME_GRUNGE",
155                 "FRAME_SUMI_E",
156                 "FRAME_TAPE",
157                 "FRAME_BLACK",
158                 "FRAME_BLACK_ROUNDED",
159                 "FRAME_WHITE",
160                 "FRAME_WHITE_ROUNDED",
161                 "FRAME_CREAM",
162                 "FRAME_CREAM_ROUNDED"
163         };
164 
165         // The "no border" implementation
166         int i = 0;
167         FilterRepresentation rep = new FilterImageBorderRepresentation(0);
168         mBorders.add(rep);
169 
170         // Regular borders
171         ArrayList <FilterRepresentation> borderList = new ArrayList<FilterRepresentation>();
172 
173 
174         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_4x5);
175         borderList.add(rep);
176 
177         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_brush);
178         borderList.add(rep);
179 
180         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_grunge);
181         borderList.add(rep);
182 
183         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_sumi_e);
184         borderList.add(rep);
185 
186         rep = new FilterImageBorderRepresentation(R.drawable.filtershow_border_tape);
187         borderList.add(rep);
188 
189         rep = new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize, 0);
190         borderList.add(rep);
191 
192         rep = new FilterColorBorderRepresentation(Color.BLACK, mImageBorderSize,
193                 mImageBorderSize);
194         borderList.add(rep);
195 
196         rep = new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize, 0);
197         borderList.add(rep);
198 
199         rep = new FilterColorBorderRepresentation(Color.WHITE, mImageBorderSize,
200                 mImageBorderSize);
201         borderList.add(rep);
202 
203         int creamColor = Color.argb(255, 237, 237, 227);
204         rep = new FilterColorBorderRepresentation(creamColor, mImageBorderSize, 0);
205         borderList.add(rep);
206 
207         rep = new FilterColorBorderRepresentation(creamColor, mImageBorderSize,
208                 mImageBorderSize);
209         borderList.add(rep);
210 
211         for (FilterRepresentation filter : borderList) {
212             filter.setSerializationName(serializationNames[i++]);
213             addRepresentation(filter);
214             mBorders.add(filter);
215         }
216 
217     }
218 
addLooks(Context context)219     public void addLooks(Context context) {
220         int[] drawid = {
221                 R.drawable.filtershow_fx_0005_punch,
222                 R.drawable.filtershow_fx_0000_vintage,
223                 R.drawable.filtershow_fx_0004_bw_contrast,
224                 R.drawable.filtershow_fx_0002_bleach,
225                 R.drawable.filtershow_fx_0001_instant,
226                 R.drawable.filtershow_fx_0007_washout,
227                 R.drawable.filtershow_fx_0003_blue_crush,
228                 R.drawable.filtershow_fx_0008_washout_color,
229                 R.drawable.filtershow_fx_0006_x_process
230         };
231 
232         int[] fxNameid = {
233                 R.string.ffx_punch,
234                 R.string.ffx_vintage,
235                 R.string.ffx_bw_contrast,
236                 R.string.ffx_bleach,
237                 R.string.ffx_instant,
238                 R.string.ffx_washout,
239                 R.string.ffx_blue_crush,
240                 R.string.ffx_washout_color,
241                 R.string.ffx_x_process
242         };
243 
244         // Do not localize.
245         String[] serializationNames = {
246                 "LUT3D_PUNCH",
247                 "LUT3D_VINTAGE",
248                 "LUT3D_BW",
249                 "LUT3D_BLEACH",
250                 "LUT3D_INSTANT",
251                 "LUT3D_WASHOUT",
252                 "LUT3D_BLUECRUSH",
253                 "LUT3D_WASHOUT_COLOR",
254                 "LUT3D_XPROCESS"
255         };
256 
257         FilterFxRepresentation nullFx =
258                 new FilterFxRepresentation(context.getString(R.string.none),
259                         0, R.string.none);
260         mLooks.add(nullFx);
261 
262         for (int i = 0; i < drawid.length; i++) {
263             FilterFxRepresentation fx = new FilterFxRepresentation(
264                     context.getString(fxNameid[i]), drawid[i], fxNameid[i]);
265             fx.setSerializationName(serializationNames[i]);
266             ImagePreset preset = new ImagePreset();
267             preset.addFilter(fx);
268             FilterUserPresetRepresentation rep = new FilterUserPresetRepresentation(
269                     context.getString(fxNameid[i]), preset, -1);
270             mLooks.add(rep);
271             addRepresentation(fx);
272         }
273     }
274 
addEffects()275     public void addEffects() {
276         mEffects.add(getRepresentation(ImageFilterTinyPlanet.class));
277         mEffects.add(getRepresentation(ImageFilterWBalance.class));
278         mEffects.add(getRepresentation(ImageFilterExposure.class));
279         mEffects.add(getRepresentation(ImageFilterContrast.class));
280         mEffects.add(getRepresentation(ImageFilterShadows.class));
281         mEffects.add(getRepresentation(ImageFilterHighlights.class));
282         mEffects.add(getRepresentation(ImageFilterVibrance.class));
283         mEffects.add(getRepresentation(ImageFilterCurves.class));
284         mEffects.add(getRepresentation(ImageFilterHue.class));
285         mEffects.add(getRepresentation(ImageFilterBwFilter.class));
286         mEffects.add(getRepresentation(ImageFilterNegative.class));
287         mEffects.add(getRepresentation(ImageFilterEdge.class));
288         mEffects.add(getRepresentation(ImageFilterKMeans.class));
289     }
290 
addTools(Context context)291     public void addTools(Context context) {
292 
293         int[] textId = {
294                 R.string.crop,
295                 R.string.straighten,
296                 R.string.rotate,
297                 R.string.mirror
298         };
299 
300         int[] overlayId = {
301                 R.drawable.filtershow_button_geometry_crop,
302                 R.drawable.filtershow_button_geometry_straighten,
303                 R.drawable.filtershow_button_geometry_rotate,
304                 R.drawable.filtershow_button_geometry_flip
305         };
306 
307         FilterRepresentation[] geometryFilters = {
308                 new FilterCropRepresentation(),
309                 new FilterStraightenRepresentation(),
310                 new FilterRotateRepresentation(),
311                 new FilterMirrorRepresentation()
312         };
313 
314         for (int i = 0; i < textId.length; i++) {
315             FilterRepresentation geometry = geometryFilters[i];
316             geometry.setTextId(textId[i]);
317             geometry.setOverlayId(overlayId[i]);
318             geometry.setOverlayOnly(true);
319             if (geometry.getTextId() != 0) {
320                 geometry.setName(context.getString(geometry.getTextId()));
321             }
322             mTools.add(geometry);
323         }
324 
325         //mTools.add(getRepresentation(ImageFilterRedEye.class));
326         mTools.add(getRepresentation(ImageFilterDraw.class));
327     }
328 
removeRepresentation(ArrayList<FilterRepresentation> list, FilterRepresentation representation)329     public void removeRepresentation(ArrayList<FilterRepresentation> list,
330                                           FilterRepresentation representation) {
331         for (int i = 0; i < list.size(); i++) {
332             FilterRepresentation r = list.get(i);
333             if (r.getFilterClass() == representation.getFilterClass()) {
334                 list.remove(i);
335                 break;
336             }
337         }
338     }
339 
setFilterResources(Resources resources)340     public void setFilterResources(Resources resources) {
341         ImageFilterBorder filterBorder = (ImageFilterBorder) getFilter(ImageFilterBorder.class);
342         filterBorder.setResources(resources);
343         ImageFilterFx filterFx = (ImageFilterFx) getFilter(ImageFilterFx.class);
344         filterFx.setResources(resources);
345     }
346 }
347