Home | History | Annotate | Download | only in filters
      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 
     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 
     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 
     76         public Band() {
     77         }
     78 
     79         public Band(int x, int y) {
     80             xPos1 = x;
     81             yPos1 = y+30;
     82             xPos2 = x;
     83             yPos2 = y-30;
     84         }
     85 
     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
    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 
    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
    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
    139     public FilterRepresentation copy() {
    140         FilterGradRepresentation representation = new FilterGradRepresentation();
    141         copyAllParameters(representation);
    142         return representation;
    143     }
    144 
    145     @Override
    146     protected void copyAllParameters(FilterRepresentation representation) {
    147         super.copyAllParameters(representation);
    148         representation.useParametersFrom(this);
    149     }
    150 
    151     @Override
    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 
    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 
    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 
    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 
    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 
    268     public void setSelectedPoint(int pos) {
    269         mCurrentBand = mBands.get(pos);
    270     }
    271 
    272     public int getSelectedPoint() {
    273         return mBands.indexOf(mCurrentBand);
    274     }
    275 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    402     public void setPoint1(float x, float y) {
    403         mCurrentBand.xPos1 = (int)x;
    404         mCurrentBand.yPos1 = (int)y;
    405     }
    406 
    407     @Override
    408     public void setPoint2(float x, float y) {
    409         mCurrentBand.xPos2 = (int)x;
    410         mCurrentBand.yPos2 = (int)y;
    411     }
    412 
    413     @Override
    414     public float getPoint1X() {
    415         return mCurrentBand.xPos1;
    416     }
    417 
    418     @Override
    419     public float getPoint1Y() {
    420         return mCurrentBand.yPos1;
    421     }
    422     @Override
    423     public float getPoint2X() {
    424         return mCurrentBand.xPos2;
    425     }
    426 
    427     @Override
    428     public float getPoint2Y() {
    429         return mCurrentBand.yPos2;
    430     }
    431 
    432     @Override
    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
    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