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.graphics.Rect; 19 import android.util.JsonReader; 20 import android.util.JsonWriter; 21 22 import com.android.gallery3d.R; 23 import com.android.gallery3d.filtershow.editors.EditorGrad; 24 import com.android.gallery3d.filtershow.imageshow.MasterImage; 25 import com.android.gallery3d.filtershow.imageshow.Line; 26 27 import java.io.IOException; 28 import java.util.Vector; 29 30 public class FilterGradRepresentation extends FilterRepresentation 31 implements Line { 32 private static final String LOGTAG = "FilterGradRepresentation"; 33 public static final int MAX_POINTS = 16; 34 public static final int PARAM_BRIGHTNESS = 0; 35 public static final int PARAM_SATURATION = 1; 36 public static final int PARAM_CONTRAST = 2; 37 private static final double ADD_MIN_DIST = .05; 38 private static String LINE_NAME = "Point"; 39 private static final String SERIALIZATION_NAME = "grad"; 40 FilterGradRepresentation()41 public FilterGradRepresentation() { 42 super("Grad"); 43 setSerializationName(SERIALIZATION_NAME); 44 creatExample(); 45 setOverlayId(R.drawable.filtershow_button_grad); 46 setFilterClass(ImageFilterGrad.class); 47 setTextId(R.string.grad); 48 setEditorId(EditorGrad.ID); 49 } 50 trimVector()51 public void trimVector(){ 52 int n = mBands.size(); 53 for (int i = n; i < MAX_POINTS; i++) { 54 mBands.add(new Band()); 55 } 56 for (int i = MAX_POINTS; i < n; i++) { 57 mBands.remove(i); 58 } 59 } 60 61 Vector<Band> mBands = new Vector<Band>(); 62 Band mCurrentBand; 63 64 static class Band { 65 private boolean mask = true; 66 67 private int xPos1 = -1; 68 private int yPos1 = 100; 69 private int xPos2 = -1; 70 private int yPos2 = 100; 71 private int brightness = -40; 72 private int contrast = 0; 73 private int saturation = 0; 74 75 Band()76 public Band() { 77 } 78 Band(int x, int y)79 public Band(int x, int y) { 80 xPos1 = x; 81 yPos1 = y+30; 82 xPos2 = x; 83 yPos2 = y-30; 84 } 85 Band(Band copy)86 public Band(Band copy) { 87 mask = copy.mask; 88 xPos1 = copy.xPos1; 89 yPos1 = copy.yPos1; 90 xPos2 = copy.xPos2; 91 yPos2 = copy.yPos2; 92 brightness = copy.brightness; 93 contrast = copy.contrast; 94 saturation = copy.saturation; 95 } 96 97 } 98 99 @Override toString()100 public String toString() { 101 int count = 0; 102 for (Band point : mBands) { 103 if (!point.mask) { 104 count++; 105 } 106 } 107 return "c=" + mBands.indexOf(mCurrentBand) + "[" + mBands.size() + "]" + count; 108 } 109 creatExample()110 private void creatExample() { 111 Band p = new Band(); 112 p.mask = false; 113 p.xPos1 = -1; 114 p.yPos1 = 100; 115 p.xPos2 = -1; 116 p.yPos2 = 100; 117 p.brightness = -50; 118 p.contrast = 0; 119 p.saturation = 0; 120 mBands.add(0, p); 121 mCurrentBand = p; 122 trimVector(); 123 } 124 125 @Override useParametersFrom(FilterRepresentation a)126 public void useParametersFrom(FilterRepresentation a) { 127 FilterGradRepresentation rep = (FilterGradRepresentation) a; 128 Vector<Band> tmpBands = new Vector<Band>(); 129 int n = (rep.mCurrentBand == null) ? 0 : rep.mBands.indexOf(rep.mCurrentBand); 130 for (Band band : rep.mBands) { 131 tmpBands.add(new Band(band)); 132 } 133 mCurrentBand = null; 134 mBands = tmpBands; 135 mCurrentBand = mBands.elementAt(n); 136 } 137 138 @Override copy()139 public FilterRepresentation copy() { 140 FilterGradRepresentation representation = new FilterGradRepresentation(); 141 copyAllParameters(representation); 142 return representation; 143 } 144 145 @Override copyAllParameters(FilterRepresentation representation)146 protected void copyAllParameters(FilterRepresentation representation) { 147 super.copyAllParameters(representation); 148 representation.useParametersFrom(this); 149 } 150 151 @Override equals(FilterRepresentation representation)152 public boolean equals(FilterRepresentation representation) { 153 if (representation instanceof FilterGradRepresentation) { 154 FilterGradRepresentation rep = (FilterGradRepresentation) representation; 155 int n = getNumberOfBands(); 156 if (rep.getNumberOfBands() != n) { 157 return false; 158 } 159 for (int i = 0; i < mBands.size(); i++) { 160 Band b1 = mBands.get(i); 161 Band b2 = rep.mBands.get(i); 162 if (b1.mask != b2.mask 163 || b1.brightness != b2.brightness 164 || b1.contrast != b2.contrast 165 || b1.saturation != b2.saturation 166 || b1.xPos1 != b2.xPos1 167 || b1.xPos2 != b2.xPos2 168 || b1.yPos1 != b2.yPos1 169 || b1.yPos2 != b2.yPos2) { 170 return false; 171 } 172 } 173 return true; 174 } 175 return false; 176 } 177 getNumberOfBands()178 public int getNumberOfBands() { 179 int count = 0; 180 for (Band point : mBands) { 181 if (!point.mask) { 182 count++; 183 } 184 } 185 return count; 186 } 187 addBand(Rect rect)188 public int addBand(Rect rect) { 189 mBands.add(0, mCurrentBand = new Band(rect.centerX(), rect.centerY())); 190 mCurrentBand.mask = false; 191 int x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2; 192 int y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2; 193 double addDelta = ADD_MIN_DIST * Math.max(rect.width(), rect.height()); 194 boolean moved = true; 195 int count = 0; 196 int toMove = mBands.indexOf(mCurrentBand); 197 198 while (moved) { 199 moved = false; 200 count++; 201 if (count > 14) { 202 break; 203 } 204 205 for (Band point : mBands) { 206 if (point.mask) { 207 break; 208 } 209 } 210 211 for (Band point : mBands) { 212 if (point.mask) { 213 break; 214 } 215 int index = mBands.indexOf(point); 216 217 if (toMove != index) { 218 double dist = Math.hypot(point.xPos1 - x, point.yPos1 - y); 219 if (dist < addDelta) { 220 moved = true; 221 mCurrentBand.xPos1 += addDelta; 222 mCurrentBand.yPos1 += addDelta; 223 mCurrentBand.xPos2 += addDelta; 224 mCurrentBand.yPos2 += addDelta; 225 x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2; 226 y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2; 227 228 if (mCurrentBand.yPos1 > rect.bottom) { 229 mCurrentBand.yPos1 = (int) (rect.top + addDelta); 230 } 231 if (mCurrentBand.xPos1 > rect.right) { 232 mCurrentBand.xPos1 = (int) (rect.left + addDelta); 233 } 234 } 235 } 236 } 237 } 238 trimVector(); 239 return 0; 240 } 241 deleteCurrentBand()242 public void deleteCurrentBand() { 243 int index = mBands.indexOf(mCurrentBand); 244 mBands.remove(mCurrentBand); 245 trimVector(); 246 if (getNumberOfBands() == 0) { 247 addBand(MasterImage.getImage().getOriginalBounds()); 248 } 249 mCurrentBand = mBands.get(0); 250 } 251 nextPoint()252 public void nextPoint(){ 253 int index = mBands.indexOf(mCurrentBand); 254 int tmp = index; 255 Band point; 256 int k = 0; 257 do { 258 index = (index+1)% mBands.size(); 259 point = mBands.get(index); 260 if (k++ >= mBands.size()) { 261 break; 262 } 263 } 264 while (point.mask == true); 265 mCurrentBand = mBands.get(index); 266 } 267 setSelectedPoint(int pos)268 public void setSelectedPoint(int pos) { 269 mCurrentBand = mBands.get(pos); 270 } 271 getSelectedPoint()272 public int getSelectedPoint() { 273 return mBands.indexOf(mCurrentBand); 274 } 275 getMask()276 public boolean[] getMask() { 277 boolean[] ret = new boolean[mBands.size()]; 278 int i = 0; 279 for (Band point : mBands) { 280 ret[i++] = !point.mask; 281 } 282 return ret; 283 } 284 getXPos1()285 public int[] getXPos1() { 286 int[] ret = new int[mBands.size()]; 287 int i = 0; 288 for (Band point : mBands) { 289 ret[i++] = point.xPos1; 290 } 291 return ret; 292 } 293 getYPos1()294 public int[] getYPos1() { 295 int[] ret = new int[mBands.size()]; 296 int i = 0; 297 for (Band point : mBands) { 298 ret[i++] = point.yPos1; 299 } 300 return ret; 301 } 302 getXPos2()303 public int[] getXPos2() { 304 int[] ret = new int[mBands.size()]; 305 int i = 0; 306 for (Band point : mBands) { 307 ret[i++] = point.xPos2; 308 } 309 return ret; 310 } 311 getYPos2()312 public int[] getYPos2() { 313 int[] ret = new int[mBands.size()]; 314 int i = 0; 315 for (Band point : mBands) { 316 ret[i++] = point.yPos2; 317 } 318 return ret; 319 } 320 getBrightness()321 public int[] getBrightness() { 322 int[] ret = new int[mBands.size()]; 323 int i = 0; 324 for (Band point : mBands) { 325 ret[i++] = point.brightness; 326 } 327 return ret; 328 } 329 getContrast()330 public int[] getContrast() { 331 int[] ret = new int[mBands.size()]; 332 int i = 0; 333 for (Band point : mBands) { 334 ret[i++] = point.contrast; 335 } 336 return ret; 337 } 338 getSaturation()339 public int[] getSaturation() { 340 int[] ret = new int[mBands.size()]; 341 int i = 0; 342 for (Band point : mBands) { 343 ret[i++] = point.saturation; 344 } 345 return ret; 346 } 347 getParameter(int type)348 public int getParameter(int type) { 349 switch (type){ 350 case PARAM_BRIGHTNESS: 351 return mCurrentBand.brightness; 352 case PARAM_SATURATION: 353 return mCurrentBand.saturation; 354 case PARAM_CONTRAST: 355 return mCurrentBand.contrast; 356 } 357 throw new IllegalArgumentException("no such type " + type); 358 } 359 getParameterMax(int type)360 public int getParameterMax(int type) { 361 switch (type) { 362 case PARAM_BRIGHTNESS: 363 return 100; 364 case PARAM_SATURATION: 365 return 100; 366 case PARAM_CONTRAST: 367 return 100; 368 } 369 throw new IllegalArgumentException("no such type " + type); 370 } 371 getParameterMin(int type)372 public int getParameterMin(int type) { 373 switch (type) { 374 case PARAM_BRIGHTNESS: 375 return -100; 376 case PARAM_SATURATION: 377 return -100; 378 case PARAM_CONTRAST: 379 return -100; 380 } 381 throw new IllegalArgumentException("no such type " + type); 382 } 383 setParameter(int type, int value)384 public void setParameter(int type, int value) { 385 mCurrentBand.mask = false; 386 switch (type) { 387 case PARAM_BRIGHTNESS: 388 mCurrentBand.brightness = value; 389 break; 390 case PARAM_SATURATION: 391 mCurrentBand.saturation = value; 392 break; 393 case PARAM_CONTRAST: 394 mCurrentBand.contrast = value; 395 break; 396 default: 397 throw new IllegalArgumentException("no such type " + type); 398 } 399 } 400 401 @Override setPoint1(float x, float y)402 public void setPoint1(float x, float y) { 403 mCurrentBand.xPos1 = (int)x; 404 mCurrentBand.yPos1 = (int)y; 405 } 406 407 @Override setPoint2(float x, float y)408 public void setPoint2(float x, float y) { 409 mCurrentBand.xPos2 = (int)x; 410 mCurrentBand.yPos2 = (int)y; 411 } 412 413 @Override getPoint1X()414 public float getPoint1X() { 415 return mCurrentBand.xPos1; 416 } 417 418 @Override getPoint1Y()419 public float getPoint1Y() { 420 return mCurrentBand.yPos1; 421 } 422 @Override getPoint2X()423 public float getPoint2X() { 424 return mCurrentBand.xPos2; 425 } 426 427 @Override getPoint2Y()428 public float getPoint2Y() { 429 return mCurrentBand.yPos2; 430 } 431 432 @Override serializeRepresentation(JsonWriter writer)433 public void serializeRepresentation(JsonWriter writer) throws IOException { 434 writer.beginObject(); 435 int len = mBands.size(); 436 int count = 0; 437 438 for (int i = 0; i < len; i++) { 439 Band point = mBands.get(i); 440 if (point.mask) { 441 continue; 442 } 443 writer.name(LINE_NAME + count); 444 count++; 445 writer.beginArray(); 446 writer.value(point.xPos1); 447 writer.value(point.yPos1); 448 writer.value(point.xPos2); 449 writer.value(point.yPos2); 450 writer.value(point.brightness); 451 writer.value(point.contrast); 452 writer.value(point.saturation); 453 writer.endArray(); 454 } 455 writer.endObject(); 456 } 457 458 @Override deSerializeRepresentation(JsonReader sreader)459 public void deSerializeRepresentation(JsonReader sreader) throws IOException { 460 sreader.beginObject(); 461 Vector<Band> points = new Vector<Band>(); 462 463 while (sreader.hasNext()) { 464 String name = sreader.nextName(); 465 if (name.startsWith(LINE_NAME)) { 466 int pointNo = Integer.parseInt(name.substring(LINE_NAME.length())); 467 sreader.beginArray(); 468 Band p = new Band(); 469 p.mask = false; 470 sreader.hasNext(); 471 p.xPos1 = sreader.nextInt(); 472 sreader.hasNext(); 473 p.yPos1 = sreader.nextInt(); 474 sreader.hasNext(); 475 p.xPos2 = sreader.nextInt(); 476 sreader.hasNext(); 477 p.yPos2 = sreader.nextInt(); 478 sreader.hasNext(); 479 p.brightness = sreader.nextInt(); 480 sreader.hasNext(); 481 p.contrast = sreader.nextInt(); 482 sreader.hasNext(); 483 p.saturation = sreader.nextInt(); 484 sreader.hasNext(); 485 sreader.endArray(); 486 points.add(p); 487 488 } else { 489 sreader.skipValue(); 490 } 491 } 492 mBands = points; 493 trimVector(); 494 mCurrentBand = mBands.get(0); 495 sreader.endObject(); 496 } 497 } 498