ImagePreset.java revision 2562a98c156a55b51239fea383838a11a0292c0e
1/* 2 * Copyright (C) 2012 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 17package com.android.gallery3d.filtershow.presets; 18 19import android.graphics.Bitmap; 20import android.util.Log; 21 22import com.android.gallery3d.filtershow.ImageStateAdapter; 23import com.android.gallery3d.filtershow.cache.ImageLoader; 24import com.android.gallery3d.filtershow.filters.BaseFiltersManager; 25import com.android.gallery3d.filtershow.filters.FilterRepresentation; 26import com.android.gallery3d.filtershow.filters.FiltersManager; 27import com.android.gallery3d.filtershow.filters.ImageFilter; 28import com.android.gallery3d.filtershow.imageshow.GeometryMetadata; 29import com.android.gallery3d.filtershow.imageshow.MasterImage; 30 31import java.util.Vector; 32 33public class ImagePreset { 34 35 private static final String LOGTAG = "ImagePreset"; 36 37 private FilterRepresentation mBorder = null; 38 private float mScaleFactor = 1.0f; 39 public static final int QUALITY_ICON = 0; 40 public static final int QUALITY_PREVIEW = 1; 41 public static final int QUALITY_FINAL = 2; 42 private int mQuality = QUALITY_PREVIEW; 43 private ImageLoader mImageLoader = null; 44 45 private Vector<FilterRepresentation> mFilters = new Vector<FilterRepresentation>(); 46 47 protected String mName = "Original"; 48 private String mHistoryName = "Original"; 49 protected boolean mIsFxPreset = false; 50 51 private boolean mDoApplyGeometry = true; 52 private boolean mDoApplyFilters = true; 53 54 public final GeometryMetadata mGeoData = new GeometryMetadata(); 55 56 public ImagePreset() { 57 setup(); 58 } 59 60 public ImagePreset(String historyName) { 61 setHistoryName(historyName); 62 setup(); 63 } 64 65 public ImagePreset(ImagePreset source, String historyName) { 66 this(source); 67 if (historyName != null) { 68 setHistoryName(historyName); 69 } 70 } 71 72 public ImagePreset(ImagePreset source) { 73 try { 74 if (source.mBorder != null) { 75 mBorder = source.mBorder.clone(); 76 } 77 for (int i = 0; i < source.mFilters.size(); i++) { 78 FilterRepresentation representation = source.mFilters.elementAt(i).clone(); 79 representation.setImagePreset(this); 80 addFilter(representation); 81 } 82 } catch (java.lang.CloneNotSupportedException e) { 83 Log.v(LOGTAG, "Exception trying to clone: " + e); 84 } 85 mName = source.name(); 86 mHistoryName = source.name(); 87 mIsFxPreset = source.isFx(); 88 mImageLoader = source.getImageLoader(); 89 90 mGeoData.set(source.mGeoData); 91 } 92 93 public FilterRepresentation getFilterRepresentation(int position) { 94 FilterRepresentation representation = null; 95 try { 96 representation = mFilters.elementAt(position).clone(); 97 } catch (CloneNotSupportedException e) { 98 e.printStackTrace(); 99 } 100 return representation; 101 } 102 103 public int getPositionForRepresentation(FilterRepresentation representation) { 104 for (int i = 0; i < mFilters.size(); i++) { 105 if (mFilters.elementAt(i).getFilterClass() == representation.getFilterClass()) { 106 return i; 107 } 108 } 109 return -1; 110 } 111 112 public FilterRepresentation getFilterRepresentationCopyFrom(FilterRepresentation filterRepresentation) { 113 // TODO: add concept of position in the filters (to allow multiple instances) 114 if (filterRepresentation == null) { 115 return null; 116 } 117 int position = getPositionForRepresentation(filterRepresentation); 118 if (position == -1) { 119 return null; 120 } 121 FilterRepresentation representation = null; 122 try { 123 representation = mFilters.elementAt(position).clone(); 124 } catch (CloneNotSupportedException e) { 125 e.printStackTrace(); 126 } 127 return representation; 128 } 129 130 public void updateFilterRepresentation(FilterRepresentation representation) { 131 synchronized (mFilters) { 132 int position = getPositionForRepresentation(representation); 133 FilterRepresentation old = mFilters.elementAt(position); 134 old.useParametersFrom(representation); 135 } 136 MasterImage.getImage().invalidatePreview(); 137 } 138 139 public void setDoApplyGeometry(boolean value) { 140 mDoApplyGeometry = value; 141 } 142 143 public void setDoApplyFilters(boolean value) { 144 mDoApplyFilters = value; 145 } 146 147 public boolean getDoApplyFilters() { 148 return mDoApplyFilters; 149 } 150 151 public synchronized GeometryMetadata getGeometry() { 152 return mGeoData; 153 } 154 155 public boolean hasModifications() { 156 if (mBorder != null && !mBorder.isNil()) { 157 return true; 158 } 159 if (mGeoData.hasModifications()) { 160 return true; 161 } 162 for (int i = 0; i < mFilters.size(); i++) { 163 FilterRepresentation filter = mFilters.elementAt(i); 164 if (!filter.isNil()) { 165 return true; 166 } 167 } 168 return false; 169 } 170 171 public boolean isPanoramaSafe() { 172 if (mBorder != null && !mBorder.isNil()) { 173 return false; 174 } 175 if (mGeoData.hasModifications()) { 176 return false; 177 } 178 for (FilterRepresentation representation : mFilters) { 179 if (representation.getPriority() == FilterRepresentation.TYPE_VIGNETTE 180 && !representation.isNil()) { 181 return false; 182 } 183 if (representation.getPriority() == FilterRepresentation.TYPE_TINYPLANET 184 && !representation.isNil()) { 185 return false; 186 } 187 } 188 return true; 189 } 190 191 public synchronized void setGeometry(GeometryMetadata m) { 192 mGeoData.set(m); 193 } 194 195 private void setBorder(FilterRepresentation filter) { 196 mBorder = filter; 197 } 198 199 public boolean isFx() { 200 return mIsFxPreset; 201 } 202 203 public void setIsFx(boolean value) { 204 mIsFxPreset = value; 205 } 206 207 public void setName(String name) { 208 mName = name; 209 mHistoryName = name; 210 } 211 212 public void setHistoryName(String name) { 213 mHistoryName = name; 214 } 215 216 public ImageLoader getImageLoader() { 217 return mImageLoader; 218 } 219 220 public void setImageLoader(ImageLoader mImageLoader) { 221 this.mImageLoader = mImageLoader; 222 } 223 224 public boolean equals(ImagePreset preset) { 225 if (!same(preset)) { 226 return false; 227 } 228 if (mDoApplyFilters && preset.mDoApplyFilters) { 229 for (int i = 0; i < preset.mFilters.size(); i++) { 230 FilterRepresentation a = preset.mFilters.elementAt(i); 231 FilterRepresentation b = mFilters.elementAt(i); 232 if (!a.equals(b)) { 233 return false; 234 } 235 } 236 } 237 return true; 238 } 239 240 public boolean same(ImagePreset preset) { 241 if (preset == null) { 242 return false; 243 } 244 245 if (preset.mFilters.size() != mFilters.size()) { 246 return false; 247 } 248 249 if (!mName.equalsIgnoreCase(preset.name())) { 250 return false; 251 } 252 253 if (mDoApplyGeometry != preset.mDoApplyGeometry) { 254 return false; 255 } 256 257 if (mDoApplyGeometry && !mGeoData.equals(preset.mGeoData)) { 258 return false; 259 } 260 261 if (mDoApplyGeometry && mBorder != preset.mBorder) { 262 return false; 263 } 264 265 if (mBorder != null && !mBorder.equals(preset.mBorder)) { 266 return false; 267 } 268 269 if (mDoApplyFilters != preset.mDoApplyFilters) { 270 if (mFilters.size() > 0 || preset.mFilters.size() > 0) { 271 return false; 272 } 273 } 274 275 if (mDoApplyFilters && preset.mDoApplyFilters) { 276 for (int i = 0; i < preset.mFilters.size(); i++) { 277 FilterRepresentation a = preset.mFilters.elementAt(i); 278 FilterRepresentation b = mFilters.elementAt(i); 279 if (!a.same(b)) { 280 return false; 281 } 282 } 283 } 284 285 return true; 286 } 287 288 public int similarUpTo(ImagePreset preset) { 289 if (!mGeoData.equals(preset.mGeoData)) { 290 return -1; 291 } 292 293 for (int i = 0; i < preset.mFilters.size(); i++) { 294 FilterRepresentation a = preset.mFilters.elementAt(i); 295 if (i < mFilters.size()) { 296 FilterRepresentation b = mFilters.elementAt(i); 297 if (!a.same(b)) { 298 return i; 299 } 300 if (!a.equals(b)) { 301 return i; 302 } 303 } else { 304 return i; 305 } 306 } 307 return preset.mFilters.size(); 308 } 309 310 public String name() { 311 return mName; 312 } 313 314 public String historyName() { 315 return mHistoryName; 316 } 317 318 public void showFilters() { 319 Log.v(LOGTAG, "\\\\\\ showFilters -- " + mFilters.size() + " filters"); 320 int n = 0; 321 for (FilterRepresentation representation : mFilters) { 322 Log.v(LOGTAG, " filter " + n + " : " + representation.toString()); 323 n++; 324 } 325 Log.v(LOGTAG, "/// showFilters -- " + mFilters.size() + " filters"); 326 } 327 328 public void addFilter(FilterRepresentation representation) { 329 Log.v(LOGTAG, "*** Add Filter *** " + representation); 330 if (representation.getPriority() == FilterRepresentation.TYPE_BORDER) { 331 setHistoryName(representation.getName()); 332 setBorder(representation); 333 } else if (representation.getPriority() == FilterRepresentation.TYPE_FX) { 334 boolean found = false; 335 for (int i = 0; i < mFilters.size(); i++) { 336 int type = mFilters.elementAt(i).getPriority(); 337 if (found) { 338 if (type != FilterRepresentation.TYPE_VIGNETTE) { 339 mFilters.remove(i); 340 continue; 341 } 342 } 343 if (type == FilterRepresentation.TYPE_FX) { 344 mFilters.remove(i); 345 mFilters.add(i, representation); 346 setHistoryName(representation.getName()); 347 found = true; 348 } 349 } 350 if (!found) { 351 mFilters.add(representation); 352 setHistoryName(representation.getName()); 353 } 354 } else { 355 mFilters.add(representation); 356 setHistoryName(representation.getName()); 357 } 358 representation.setImagePreset(this); 359 } 360 361 public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) { 362 for (int i = 0; i < mFilters.size(); i++) { 363 FilterRepresentation representation = mFilters.elementAt(i); 364 if (representation.getFilterClass() == filterRepresentation.getFilterClass()) { 365 return representation; 366 } 367 } 368 if (mBorder != null && mBorder.getFilterClass() == filterRepresentation.getFilterClass()) { 369 return mBorder; 370 } 371 return null; 372 } 373 374 public void setup() { 375 // do nothing here 376 } 377 378 public Bitmap apply(Bitmap original) { 379 Bitmap bitmap = original; 380 bitmap = applyFilters(bitmap, -1, -1); 381 return applyBorder(bitmap); 382 } 383 384 public Bitmap applyGeometry(Bitmap bitmap) { 385 // Apply any transform -- 90 rotate, flip, straighten, crop 386 // Returns a new bitmap. 387 return mGeoData.apply(bitmap, mScaleFactor, mQuality); 388 } 389 390 public Bitmap applyBorder(Bitmap bitmap) { 391 if (mBorder != null && mDoApplyGeometry) { 392 ImageFilter filter = FiltersManager.getManager().getFilterForRepresentation(mBorder); 393 filter.useRepresentation(mBorder); 394 bitmap = filter.apply(bitmap, mScaleFactor, mQuality); 395 } 396 return bitmap; 397 } 398 399 public Bitmap applyFilters(Bitmap bitmap, int from, int to) { 400 401 if (mDoApplyFilters) { 402 if (from < 0) { 403 from = 0; 404 } 405 if (to == -1) { 406 to = mFilters.size(); 407 } 408 for (int i = from; i < to; i++) { 409 FilterRepresentation representation = null; 410 synchronized (mFilters) { 411 representation = mFilters.elementAt(i); 412 } 413 ImageFilter filter = FiltersManager.getManager().getFilterForRepresentation(representation); 414 filter.useRepresentation(representation); 415 bitmap = filter.apply(bitmap, mScaleFactor, mQuality); 416 } 417 } 418 419 return bitmap; 420 } 421 422 public void fillImageStateAdapter(ImageStateAdapter imageStateAdapter) { 423 if (imageStateAdapter == null) { 424 return; 425 } 426 imageStateAdapter.clear(); 427 // TODO: re-enable the state panel 428 imageStateAdapter.addAll(mFilters); 429 imageStateAdapter.notifyDataSetChanged(); 430 } 431 432 public float getScaleFactor() { 433 return mScaleFactor; 434 } 435 436 public int getQuality() { 437 return mQuality; 438 } 439 440 public void setQuality(int value) { 441 mQuality = value; 442 } 443 444 public void setScaleFactor(float value) { 445 mScaleFactor = value; 446 } 447} 448