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 17 package com.android.gallery3d.filtershow.pipeline; 18 19 import android.graphics.Bitmap; 20 import android.graphics.Rect; 21 import android.util.JsonReader; 22 import android.util.JsonWriter; 23 import android.util.Log; 24 25 import com.android.gallery3d.R; 26 import com.android.gallery3d.filtershow.cache.BitmapCache; 27 import com.android.gallery3d.filtershow.cache.ImageLoader; 28 import com.android.gallery3d.filtershow.filters.BaseFiltersManager; 29 import com.android.gallery3d.filtershow.filters.FilterCropRepresentation; 30 import com.android.gallery3d.filtershow.filters.FilterFxRepresentation; 31 import com.android.gallery3d.filtershow.filters.FilterImageBorderRepresentation; 32 import com.android.gallery3d.filtershow.filters.FilterMirrorRepresentation; 33 import com.android.gallery3d.filtershow.filters.FilterRepresentation; 34 import com.android.gallery3d.filtershow.filters.FilterRotateRepresentation; 35 import com.android.gallery3d.filtershow.filters.FilterStraightenRepresentation; 36 import com.android.gallery3d.filtershow.filters.FilterUserPresetRepresentation; 37 import com.android.gallery3d.filtershow.filters.FiltersManager; 38 import com.android.gallery3d.filtershow.filters.ImageFilter; 39 import com.android.gallery3d.filtershow.imageshow.GeometryMathUtils; 40 import com.android.gallery3d.filtershow.imageshow.PrimaryImage; 41 import com.android.gallery3d.filtershow.state.State; 42 import com.android.gallery3d.filtershow.state.StateAdapter; 43 44 import java.io.IOException; 45 import java.io.StringReader; 46 import java.io.StringWriter; 47 import java.util.ArrayList; 48 import java.util.Collection; 49 import java.util.Vector; 50 51 public class ImagePreset { 52 53 private static final String LOGTAG = "ImagePreset"; 54 public static final String JASON_SAVED = "Saved"; 55 56 private Vector<FilterRepresentation> mFilters = new Vector<FilterRepresentation>(); 57 58 private boolean mDoApplyGeometry = true; 59 private boolean mDoApplyFilters = true; 60 61 private boolean mPartialRendering = false; 62 private Rect mPartialRenderingBounds; 63 private static final boolean DEBUG = false; 64 ImagePreset()65 public ImagePreset() { 66 } 67 ImagePreset(ImagePreset source)68 public ImagePreset(ImagePreset source) { 69 for (int i = 0; i < source.mFilters.size(); i++) { 70 FilterRepresentation sourceRepresentation = source.mFilters.elementAt(i); 71 mFilters.add(sourceRepresentation.copy()); 72 } 73 } 74 getFilters()75 public Vector<FilterRepresentation> getFilters() { 76 return mFilters; 77 } 78 getFilterRepresentation(int position)79 public FilterRepresentation getFilterRepresentation(int position) { 80 FilterRepresentation representation = null; 81 82 representation = mFilters.elementAt(position).copy(); 83 84 return representation; 85 } 86 sameSerializationName(String a, String b)87 private static boolean sameSerializationName(String a, String b) { 88 if (a != null && b != null) { 89 return a.equals(b); 90 } else { 91 return a == null && b == null; 92 } 93 } 94 sameSerializationName(FilterRepresentation a, FilterRepresentation b)95 public static boolean sameSerializationName(FilterRepresentation a, FilterRepresentation b) { 96 if (a == null || b == null) { 97 return false; 98 } 99 return sameSerializationName(a.getSerializationName(), b.getSerializationName()); 100 } 101 getPositionForRepresentation(FilterRepresentation representation)102 public int getPositionForRepresentation(FilterRepresentation representation) { 103 for (int i = 0; i < mFilters.size(); i++) { 104 if (sameSerializationName(mFilters.elementAt(i), representation)) { 105 return i; 106 } 107 } 108 return -1; 109 } 110 getFilterRepresentationForType(int type)111 private FilterRepresentation getFilterRepresentationForType(int type) { 112 for (int i = 0; i < mFilters.size(); i++) { 113 if (mFilters.elementAt(i).getFilterType() == type) { 114 return mFilters.elementAt(i); 115 } 116 } 117 return null; 118 } 119 getPositionForType(int type)120 public int getPositionForType(int type) { 121 for (int i = 0; i < mFilters.size(); i++) { 122 if (mFilters.elementAt(i).getFilterType() == type) { 123 return i; 124 } 125 } 126 return -1; 127 } 128 getFilterRepresentationCopyFrom( FilterRepresentation filterRepresentation)129 public FilterRepresentation getFilterRepresentationCopyFrom( 130 FilterRepresentation filterRepresentation) { 131 // TODO: add concept of position in the filters (to allow multiple instances) 132 if (filterRepresentation == null) { 133 return null; 134 } 135 int position = getPositionForRepresentation(filterRepresentation); 136 if (position == -1) { 137 return null; 138 } 139 FilterRepresentation representation = mFilters.elementAt(position); 140 if (representation != null) { 141 representation = representation.copy(); 142 } 143 return representation; 144 } 145 updateFilterRepresentations(Collection<FilterRepresentation> reps)146 public void updateFilterRepresentations(Collection<FilterRepresentation> reps) { 147 for (FilterRepresentation r : reps) { 148 updateOrAddFilterRepresentation(r); 149 } 150 } 151 updateOrAddFilterRepresentation(FilterRepresentation rep)152 public void updateOrAddFilterRepresentation(FilterRepresentation rep) { 153 int pos = getPositionForRepresentation(rep); 154 if (pos != -1) { 155 mFilters.elementAt(pos).useParametersFrom(rep); 156 } else { 157 addFilter(rep.copy()); 158 } 159 } 160 setDoApplyGeometry(boolean value)161 public void setDoApplyGeometry(boolean value) { 162 mDoApplyGeometry = value; 163 } 164 setDoApplyFilters(boolean value)165 public void setDoApplyFilters(boolean value) { 166 mDoApplyFilters = value; 167 } 168 getDoApplyFilters()169 public boolean getDoApplyFilters() { 170 return mDoApplyFilters; 171 } 172 hasModifications()173 public boolean hasModifications() { 174 for (int i = 0; i < mFilters.size(); i++) { 175 FilterRepresentation filter = mFilters.elementAt(i); 176 if (!filter.isNil()) { 177 return true; 178 } 179 } 180 return false; 181 } 182 contains(byte type)183 public boolean contains(byte type) { 184 for (FilterRepresentation representation : mFilters) { 185 if (representation.getFilterType() == type 186 && !representation.isNil()) { 187 return true; 188 } 189 } 190 return false; 191 } 192 isPanoramaSafe()193 public boolean isPanoramaSafe() { 194 for (FilterRepresentation representation : mFilters) { 195 if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY 196 && !representation.isNil()) { 197 return false; 198 } 199 if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER 200 && !representation.isNil()) { 201 return false; 202 } 203 if (representation.getFilterType() == FilterRepresentation.TYPE_VIGNETTE 204 && !representation.isNil()) { 205 return false; 206 } 207 if (representation.getFilterType() == FilterRepresentation.TYPE_TINYPLANET 208 && !representation.isNil()) { 209 return false; 210 } 211 } 212 return true; 213 } 214 same(ImagePreset preset)215 public boolean same(ImagePreset preset) { 216 if (preset == null) { 217 return false; 218 } 219 220 if (preset.mFilters.size() != mFilters.size()) { 221 return false; 222 } 223 224 if (mDoApplyGeometry != preset.mDoApplyGeometry) { 225 return false; 226 } 227 228 if (mDoApplyFilters != preset.mDoApplyFilters) { 229 if (mFilters.size() > 0 || preset.mFilters.size() > 0) { 230 return false; 231 } 232 } 233 234 if (mDoApplyFilters && preset.mDoApplyFilters) { 235 for (int i = 0; i < preset.mFilters.size(); i++) { 236 FilterRepresentation a = preset.mFilters.elementAt(i); 237 FilterRepresentation b = mFilters.elementAt(i); 238 239 if (!a.same(b)) { 240 return false; 241 } 242 } 243 } 244 245 return true; 246 } 247 equals(ImagePreset preset)248 public boolean equals(ImagePreset preset) { 249 if (preset == null) { 250 return false; 251 } 252 253 if (preset.mFilters.size() != mFilters.size()) { 254 return false; 255 } 256 257 if (mDoApplyGeometry != preset.mDoApplyGeometry) { 258 return false; 259 } 260 261 if (mDoApplyFilters != preset.mDoApplyFilters) { 262 if (mFilters.size() > 0 || preset.mFilters.size() > 0) { 263 return false; 264 } 265 } 266 267 for (int i = 0; i < preset.mFilters.size(); i++) { 268 FilterRepresentation a = preset.mFilters.elementAt(i); 269 FilterRepresentation b = mFilters.elementAt(i); 270 boolean isGeometry = false; 271 if (a instanceof FilterRotateRepresentation 272 || a instanceof FilterMirrorRepresentation 273 || a instanceof FilterCropRepresentation 274 || a instanceof FilterStraightenRepresentation) { 275 isGeometry = true; 276 } 277 boolean evaluate = true; 278 if (!isGeometry && mDoApplyGeometry && !mDoApplyFilters) { 279 evaluate = false; 280 } else if (isGeometry && !mDoApplyGeometry && mDoApplyFilters) { 281 evaluate = false; 282 } 283 if (evaluate && !a.equals(b)) { 284 return false; 285 } 286 } 287 288 return true; 289 } 290 similarUpTo(ImagePreset preset)291 public int similarUpTo(ImagePreset preset) { 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 showFilters()309 public void showFilters() { 310 Log.v(LOGTAG, "\\\\\\ showFilters -- " + mFilters.size() + " filters"); 311 int n = 0; 312 for (FilterRepresentation representation : mFilters) { 313 Log.v(LOGTAG, " filter " + n + " : " + representation.toString()); 314 n++; 315 } 316 Log.v(LOGTAG, "/// showFilters -- " + mFilters.size() + " filters"); 317 } 318 getLastRepresentation()319 public FilterRepresentation getLastRepresentation() { 320 if (mFilters.size() > 0) { 321 return mFilters.lastElement(); 322 } 323 return null; 324 } 325 removeFilter(FilterRepresentation filterRepresentation)326 public void removeFilter(FilterRepresentation filterRepresentation) { 327 if (filterRepresentation.getFilterType() == FilterRepresentation.TYPE_BORDER) { 328 for (int i = 0; i < mFilters.size(); i++) { 329 if (mFilters.elementAt(i).getFilterType() 330 == filterRepresentation.getFilterType()) { 331 mFilters.remove(i); 332 break; 333 } 334 } 335 } else { 336 for (int i = 0; i < mFilters.size(); i++) { 337 if (sameSerializationName(mFilters.elementAt(i), filterRepresentation)) { 338 mFilters.remove(i); 339 break; 340 } 341 } 342 } 343 } 344 345 // If the filter is an "None" effect or border, then just don't add this filter. addFilter(FilterRepresentation representation)346 public void addFilter(FilterRepresentation representation) { 347 if (representation instanceof FilterUserPresetRepresentation) { 348 ImagePreset preset = ((FilterUserPresetRepresentation) representation).getImagePreset(); 349 if (preset.nbFilters() == 1 350 && preset.contains(FilterRepresentation.TYPE_FX)) { 351 FilterRepresentation rep = preset.getFilterRepresentationForType( 352 FilterRepresentation.TYPE_FX); 353 addFilter(rep); 354 } else { 355 // user preset replaces everything 356 mFilters.clear(); 357 for (int i = 0; i < preset.nbFilters(); i++) { 358 addFilter(preset.getFilterRepresentation(i)); 359 } 360 } 361 } else if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) { 362 // Add geometry filter, removing duplicates and do-nothing operations. 363 for (int i = 0; i < mFilters.size(); i++) { 364 if (sameSerializationName(representation, mFilters.elementAt(i))) { 365 mFilters.remove(i); 366 } 367 } 368 int index = 0; 369 for (; index < mFilters.size(); index++) { 370 FilterRepresentation rep = mFilters.elementAt(index); 371 if (rep.getFilterType() != FilterRepresentation.TYPE_GEOMETRY) { 372 break; 373 } 374 } 375 if (!representation.isNil()) { 376 mFilters.insertElementAt(representation, index); 377 } 378 } else if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { 379 removeFilter(representation); 380 if (!isNoneBorderFilter(representation)) { 381 mFilters.add(representation); 382 } 383 } else if (representation.getFilterType() == FilterRepresentation.TYPE_FX) { 384 boolean replaced = false; 385 for (int i = 0; i < mFilters.size(); i++) { 386 FilterRepresentation current = mFilters.elementAt(i); 387 if (current.getFilterType() == FilterRepresentation.TYPE_FX) { 388 mFilters.remove(i); 389 replaced = true; 390 if (!isNoneFxFilter(representation)) { 391 mFilters.add(i, representation); 392 } 393 break; 394 } 395 } 396 if (!replaced && !isNoneFxFilter(representation)) { 397 mFilters.add(0, representation); 398 } 399 } else { 400 mFilters.add(representation); 401 } 402 // Enforces Filter type ordering for borders 403 FilterRepresentation border = null; 404 for (int i = 0; i < mFilters.size();) { 405 FilterRepresentation rep = mFilters.elementAt(i); 406 if (rep.getFilterType() == FilterRepresentation.TYPE_BORDER) { 407 border = rep; 408 mFilters.remove(i); 409 continue; 410 } 411 i++; 412 } 413 if (border != null) { 414 mFilters.add(border); 415 } 416 } 417 isNoneBorderFilter(FilterRepresentation representation)418 private boolean isNoneBorderFilter(FilterRepresentation representation) { 419 return representation instanceof FilterImageBorderRepresentation && 420 ((FilterImageBorderRepresentation) representation).getDrawableResource() == 0; 421 } 422 isNoneFxFilter(FilterRepresentation representation)423 private boolean isNoneFxFilter(FilterRepresentation representation) { 424 return representation instanceof FilterFxRepresentation && 425 ((FilterFxRepresentation) representation).getNameResource() == R.string.none; 426 } 427 getRepresentation(FilterRepresentation filterRepresentation)428 public FilterRepresentation getRepresentation(FilterRepresentation filterRepresentation) { 429 for (int i = 0; i < mFilters.size(); i++) { 430 FilterRepresentation representation = mFilters.elementAt(i); 431 if (sameSerializationName(representation, filterRepresentation)) { 432 return representation; 433 } 434 } 435 return null; 436 } 437 apply(Bitmap original, FilterEnvironment environment)438 public Bitmap apply(Bitmap original, FilterEnvironment environment) { 439 Bitmap bitmap = original; 440 bitmap = applyFilters(bitmap, -1, -1, environment); 441 return applyBorder(bitmap, environment); 442 } 443 getGeometryFilters()444 public Collection<FilterRepresentation> getGeometryFilters() { 445 ArrayList<FilterRepresentation> geometry = new ArrayList<FilterRepresentation>(); 446 for (FilterRepresentation r : mFilters) { 447 if (r.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) { 448 geometry.add(r); 449 } 450 } 451 return geometry; 452 } 453 getFilterWithSerializationName(String serializationName)454 public FilterRepresentation getFilterWithSerializationName(String serializationName) { 455 for (FilterRepresentation r : mFilters) { 456 if (r != null) { 457 if (sameSerializationName(r.getSerializationName(), serializationName)) { 458 return r.copy(); 459 } 460 } 461 } 462 return null; 463 } 464 finalGeometryRect(int width, int height)465 public Rect finalGeometryRect(int width, int height) { 466 return GeometryMathUtils.finalGeometryRect(width, height, getGeometryFilters()); 467 } 468 applyGeometry(Bitmap bitmap, FilterEnvironment environment)469 public Bitmap applyGeometry(Bitmap bitmap, FilterEnvironment environment) { 470 // Apply any transform -- 90 rotate, flip, straighten, crop 471 // Returns a new bitmap. 472 if (mDoApplyGeometry) { 473 Bitmap bmp = GeometryMathUtils.applyGeometryRepresentations( 474 getGeometryFilters(), bitmap); 475 if (bmp != bitmap) { 476 environment.cache(bitmap); 477 } 478 return bmp; 479 } 480 return bitmap; 481 } 482 applyBorder(Bitmap bitmap, FilterEnvironment environment)483 public Bitmap applyBorder(Bitmap bitmap, FilterEnvironment environment) { 484 // get the border from the list of filters. 485 FilterRepresentation border = getFilterRepresentationForType( 486 FilterRepresentation.TYPE_BORDER); 487 if (border != null && mDoApplyGeometry) { 488 bitmap = environment.applyRepresentation(border, bitmap); 489 if (environment.getQuality() == FilterEnvironment.QUALITY_FINAL) { 490 } 491 } 492 return bitmap; 493 } 494 nbFilters()495 public int nbFilters() { 496 return mFilters.size(); 497 } 498 applyFilters(Bitmap bitmap, int from, int to, FilterEnvironment environment)499 public Bitmap applyFilters(Bitmap bitmap, int from, int to, FilterEnvironment environment) { 500 if (mDoApplyFilters) { 501 if (from < 0) { 502 from = 0; 503 } 504 if (to == -1) { 505 to = mFilters.size(); 506 } 507 for (int i = from; i < to; i++) { 508 FilterRepresentation representation = mFilters.elementAt(i); 509 if (representation.getFilterType() == FilterRepresentation.TYPE_GEOMETRY) { 510 // skip the geometry as it's already applied. 511 continue; 512 } 513 if (representation.getFilterType() == FilterRepresentation.TYPE_BORDER) { 514 // for now, let's skip the border as it will be applied in 515 // applyBorder() 516 // TODO: might be worth getting rid of applyBorder. 517 continue; 518 } 519 Bitmap tmp = bitmap; 520 bitmap = environment.applyRepresentation(representation, bitmap); 521 if (tmp != bitmap) { 522 environment.cache(tmp); 523 } 524 if (environment.needsStop()) { 525 return bitmap; 526 } 527 } 528 } 529 530 return bitmap; 531 } 532 canDoPartialRendering()533 public boolean canDoPartialRendering() { 534 if (PrimaryImage.getImage().getZoomOrientation() != ImageLoader.ORI_NORMAL) { 535 return false; 536 } 537 for (int i = 0; i < mFilters.size(); i++) { 538 FilterRepresentation representation = mFilters.elementAt(i); 539 if (!representation.supportsPartialRendering()) { 540 return false; 541 } 542 } 543 return true; 544 } 545 fillImageStateAdapter(StateAdapter imageStateAdapter)546 public void fillImageStateAdapter(StateAdapter imageStateAdapter) { 547 if (imageStateAdapter == null) { 548 return; 549 } 550 Vector<State> states = new Vector<State>(); 551 for (FilterRepresentation filter : mFilters) { 552 if (filter instanceof FilterUserPresetRepresentation) { 553 // do not show the user preset itself in the state panel 554 continue; 555 } 556 State state = new State(filter.getName()); 557 state.setFilterRepresentation(filter); 558 states.add(state); 559 } 560 imageStateAdapter.fill(states); 561 } 562 setPartialRendering(boolean partialRendering, Rect bounds)563 public void setPartialRendering(boolean partialRendering, Rect bounds) { 564 mPartialRendering = partialRendering; 565 mPartialRenderingBounds = bounds; 566 } 567 isPartialRendering()568 public boolean isPartialRendering() { 569 return mPartialRendering; 570 } 571 getPartialRenderingBounds()572 public Rect getPartialRenderingBounds() { 573 return mPartialRenderingBounds; 574 } 575 getUsedFilters(BaseFiltersManager filtersManager)576 public Vector<ImageFilter> getUsedFilters(BaseFiltersManager filtersManager) { 577 Vector<ImageFilter> usedFilters = new Vector<ImageFilter>(); 578 for (int i = 0; i < mFilters.size(); i++) { 579 FilterRepresentation representation = mFilters.elementAt(i); 580 ImageFilter filter = filtersManager.getFilterForRepresentation(representation); 581 usedFilters.add(filter); 582 } 583 return usedFilters; 584 } 585 getJsonString(String name)586 public String getJsonString(String name) { 587 StringWriter swriter = new StringWriter(); 588 try { 589 JsonWriter writer = new JsonWriter(swriter); 590 writeJson(writer, name); 591 writer.close(); 592 } catch (IOException e) { 593 return null; 594 } 595 return swriter.toString(); 596 } 597 writeJson(JsonWriter writer, String name)598 public void writeJson(JsonWriter writer, String name) { 599 int numFilters = mFilters.size(); 600 try { 601 writer.beginObject(); 602 for (int i = 0; i < numFilters; i++) { 603 FilterRepresentation filter = mFilters.get(i); 604 if (filter instanceof FilterUserPresetRepresentation) { 605 continue; 606 } 607 String sname = filter.getSerializationName(); 608 if (DEBUG) { 609 Log.v(LOGTAG, "Serialization: " + sname); 610 if (sname == null) { 611 Log.v(LOGTAG, "Serialization name null for filter: " + filter); 612 } 613 } 614 writer.name(sname); 615 filter.serializeRepresentation(writer); 616 } 617 writer.endObject(); 618 619 } catch (IOException e) { 620 Log.e(LOGTAG,"Error encoding JASON",e); 621 } 622 } 623 624 /** 625 * populates preset from JSON string 626 * 627 * @param filterString a JSON string 628 * @return true on success if false ImagePreset is undefined 629 */ readJsonFromString(String filterString)630 public boolean readJsonFromString(String filterString) { 631 if (DEBUG) { 632 Log.v(LOGTAG, "reading preset: \"" + filterString + "\""); 633 } 634 StringReader sreader = new StringReader(filterString); 635 try { 636 JsonReader reader = new JsonReader(sreader); 637 boolean ok = readJson(reader); 638 if (!ok) { 639 reader.close(); 640 return false; 641 } 642 reader.close(); 643 } catch (Exception e) { 644 Log.e(LOGTAG, "\""+filterString+"\""); 645 Log.e(LOGTAG, "parsing the filter parameters:", e); 646 return false; 647 } 648 return true; 649 } 650 651 /** 652 * populates preset from JSON stream 653 * 654 * @param sreader a JSON string 655 * @return true on success if false ImagePreset is undefined 656 */ readJson(JsonReader sreader)657 public boolean readJson(JsonReader sreader) throws IOException { 658 sreader.beginObject(); 659 660 while (sreader.hasNext()) { 661 String name = sreader.nextName(); 662 FilterRepresentation filter = creatFilterFromName(name); 663 if (filter == null) { 664 Log.w(LOGTAG, "UNKNOWN FILTER! " + name); 665 return false; 666 } 667 filter.deSerializeRepresentation(sreader); 668 addFilter(filter); 669 } 670 sreader.endObject(); 671 return true; 672 } 673 creatFilterFromName(String name)674 FilterRepresentation creatFilterFromName(String name) { 675 if (FilterRotateRepresentation.SERIALIZATION_NAME.equals(name)) { 676 return new FilterRotateRepresentation(); 677 } else if (FilterMirrorRepresentation.SERIALIZATION_NAME.equals(name)) { 678 return new FilterMirrorRepresentation(); 679 } else if (FilterStraightenRepresentation.SERIALIZATION_NAME.equals(name)) { 680 return new FilterStraightenRepresentation(); 681 } else if (FilterCropRepresentation.SERIALIZATION_NAME.equals(name)) { 682 return new FilterCropRepresentation(); 683 } 684 FiltersManager filtersManager = FiltersManager.getManager(); 685 return filtersManager.createFilterFromName(name); 686 } 687 updateWith(ImagePreset preset)688 public void updateWith(ImagePreset preset) { 689 if (preset.mFilters.size() != mFilters.size()) { 690 Log.e(LOGTAG, "Updating a preset with an incompatible one"); 691 return; 692 } 693 for (int i = 0; i < mFilters.size(); i++) { 694 FilterRepresentation destRepresentation = mFilters.elementAt(i); 695 FilterRepresentation sourceRepresentation = preset.mFilters.elementAt(i); 696 destRepresentation.useParametersFrom(sourceRepresentation); 697 } 698 } 699 } 700