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