/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.gallery3d.filtershow.filters; import android.graphics.Rect; import android.util.JsonReader; import android.util.JsonWriter; import com.android.gallery3d.R; import com.android.gallery3d.filtershow.editors.EditorGrad; import com.android.gallery3d.filtershow.imageshow.MasterImage; import com.android.gallery3d.filtershow.imageshow.Line; import java.io.IOException; import java.util.Vector; public class FilterGradRepresentation extends FilterRepresentation implements Line { private static final String LOGTAG = "FilterGradRepresentation"; public static final int MAX_POINTS = 16; public static final int PARAM_BRIGHTNESS = 0; public static final int PARAM_SATURATION = 1; public static final int PARAM_CONTRAST = 2; private static final double ADD_MIN_DIST = .05; private static String LINE_NAME = "Point"; private static final String SERIALIZATION_NAME = "grad"; public FilterGradRepresentation() { super("Grad"); setSerializationName(SERIALIZATION_NAME); creatExample(); setOverlayId(R.drawable.filtershow_button_grad); setFilterClass(ImageFilterGrad.class); setTextId(R.string.grad); setEditorId(EditorGrad.ID); } public void trimVector(){ int n = mBands.size(); for (int i = n; i < MAX_POINTS; i++) { mBands.add(new Band()); } for (int i = MAX_POINTS; i < n; i++) { mBands.remove(i); } } Vector mBands = new Vector(); Band mCurrentBand; static class Band { private boolean mask = true; private int xPos1 = -1; private int yPos1 = 100; private int xPos2 = -1; private int yPos2 = 100; private int brightness = 40; private int contrast = 0; private int saturation = 0; public Band() { } public Band(int x, int y) { xPos1 = x; yPos1 = y+30; xPos2 = x; yPos2 = y-30; } public Band(Band copy) { mask = copy.mask; xPos1 = copy.xPos1; yPos1 = copy.yPos1; xPos2 = copy.xPos2; yPos2 = copy.yPos2; brightness = copy.brightness; contrast = copy.contrast; saturation = copy.saturation; } } @Override public String toString() { int count = 0; for (Band point : mBands) { if (!point.mask) { count++; } } return "c=" + mBands.indexOf(mBands) + "[" + mBands.size() + "]" + count; } private void creatExample() { Band p = new Band(); p.mask = false; p.xPos1 = -1; p.yPos1 = 100; p.xPos2 = -1; p.yPos2 = 100; p.brightness = 40; p.contrast = 0; p.saturation = 0; mBands.add(0, p); mCurrentBand = p; trimVector(); } @Override public void useParametersFrom(FilterRepresentation a) { FilterGradRepresentation rep = (FilterGradRepresentation) a; Vector tmpBands = new Vector(); int n = (rep.mCurrentBand == null) ? 0 : rep.mBands.indexOf(rep.mCurrentBand); for (Band band : rep.mBands) { tmpBands.add(new Band(band)); } mCurrentBand = null; mBands = tmpBands; mCurrentBand = mBands.elementAt(n); } @Override public FilterRepresentation copy() { FilterGradRepresentation representation = new FilterGradRepresentation(); copyAllParameters(representation); return representation; } @Override protected void copyAllParameters(FilterRepresentation representation) { super.copyAllParameters(representation); representation.useParametersFrom(this); } @Override public boolean equals(FilterRepresentation representation) { if (representation instanceof FilterGradRepresentation) { FilterGradRepresentation rep = (FilterGradRepresentation) representation; int n = getNumberOfBands(); if (rep.getNumberOfBands() != n) { return false; } for (int i = 0; i < mBands.size(); i++) { Band b1 = mBands.get(i); Band b2 = rep.mBands.get(i); if (b1.mask != b2.mask || b1.brightness != b2.brightness || b1.contrast != b2.contrast || b1.saturation != b2.saturation || b1.xPos1 != b2.xPos1 || b1.xPos2 != b2.xPos2 || b1.yPos1 != b2.yPos1 || b1.yPos2 != b2.yPos2) { return false; } } return true; } return false; } public int getNumberOfBands() { int count = 0; for (Band point : mBands) { if (!point.mask) { count++; } } return count; } public int addBand(Rect rect) { mBands.add(0, mCurrentBand = new Band(rect.centerX(), rect.centerY())); mCurrentBand.mask = false; int x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2; int y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2; double addDelta = ADD_MIN_DIST * Math.max(rect.width(), rect.height()); boolean moved = true; int count = 0; int toMove = mBands.indexOf(mCurrentBand); while (moved) { moved = false; count++; if (count > 14) { break; } for (Band point : mBands) { if (point.mask) { break; } } for (Band point : mBands) { if (point.mask) { break; } int index = mBands.indexOf(point); if (toMove != index) { double dist = Math.hypot(point.xPos1 - x, point.yPos1 - y); if (dist < addDelta) { moved = true; mCurrentBand.xPos1 += addDelta; mCurrentBand.yPos1 += addDelta; mCurrentBand.xPos2 += addDelta; mCurrentBand.yPos2 += addDelta; x = (mCurrentBand.xPos1 + mCurrentBand.xPos2)/2; y = (mCurrentBand.yPos1 + mCurrentBand.yPos2)/2; if (mCurrentBand.yPos1 > rect.bottom) { mCurrentBand.yPos1 = (int) (rect.top + addDelta); } if (mCurrentBand.xPos1 > rect.right) { mCurrentBand.xPos1 = (int) (rect.left + addDelta); } } } } } trimVector(); return 0; } public void deleteCurrentBand() { int index = mBands.indexOf(mCurrentBand); mBands.remove(mCurrentBand); trimVector(); if (getNumberOfBands() == 0) { addBand(MasterImage.getImage().getOriginalBounds()); } mCurrentBand = mBands.get(0); } public void nextPoint(){ int index = mBands.indexOf(mCurrentBand); int tmp = index; Band point; int k = 0; do { index = (index+1)% mBands.size(); point = mBands.get(index); if (k++ >= mBands.size()) { break; } } while (point.mask == true); mCurrentBand = mBands.get(index); } public void setSelectedPoint(int pos) { mCurrentBand = mBands.get(pos); } public int getSelectedPoint() { return mBands.indexOf(mCurrentBand); } public boolean[] getMask() { boolean[] ret = new boolean[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = !point.mask; } return ret; } public int[] getXPos1() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.xPos1; } return ret; } public int[] getYPos1() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.yPos1; } return ret; } public int[] getXPos2() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.xPos2; } return ret; } public int[] getYPos2() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.yPos2; } return ret; } public int[] getBrightness() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.brightness; } return ret; } public int[] getContrast() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.contrast; } return ret; } public int[] getSaturation() { int[] ret = new int[mBands.size()]; int i = 0; for (Band point : mBands) { ret[i++] = point.saturation; } return ret; } public int getParameter(int type) { switch (type){ case PARAM_BRIGHTNESS: return mCurrentBand.brightness; case PARAM_SATURATION: return mCurrentBand.saturation; case PARAM_CONTRAST: return mCurrentBand.contrast; } throw new IllegalArgumentException("no such type " + type); } public int getParameterMax(int type) { switch (type) { case PARAM_BRIGHTNESS: return 100; case PARAM_SATURATION: return 100; case PARAM_CONTRAST: return 100; } throw new IllegalArgumentException("no such type " + type); } public int getParameterMin(int type) { switch (type) { case PARAM_BRIGHTNESS: return -100; case PARAM_SATURATION: return -100; case PARAM_CONTRAST: return -100; } throw new IllegalArgumentException("no such type " + type); } public void setParameter(int type, int value) { mCurrentBand.mask = false; switch (type) { case PARAM_BRIGHTNESS: mCurrentBand.brightness = value; break; case PARAM_SATURATION: mCurrentBand.saturation = value; break; case PARAM_CONTRAST: mCurrentBand.contrast = value; break; default: throw new IllegalArgumentException("no such type " + type); } } @Override public void setPoint1(float x, float y) { mCurrentBand.xPos1 = (int)x; mCurrentBand.yPos1 = (int)y; } @Override public void setPoint2(float x, float y) { mCurrentBand.xPos2 = (int)x; mCurrentBand.yPos2 = (int)y; } @Override public float getPoint1X() { return mCurrentBand.xPos1; } @Override public float getPoint1Y() { return mCurrentBand.yPos1; } @Override public float getPoint2X() { return mCurrentBand.xPos2; } @Override public float getPoint2Y() { return mCurrentBand.yPos2; } @Override public void serializeRepresentation(JsonWriter writer) throws IOException { writer.beginObject(); int len = mBands.size(); int count = 0; for (int i = 0; i < len; i++) { Band point = mBands.get(i); if (point.mask) { continue; } writer.name(LINE_NAME + count); count++; writer.beginArray(); writer.value(point.xPos1); writer.value(point.yPos1); writer.value(point.xPos2); writer.value(point.yPos2); writer.value(point.brightness); writer.value(point.contrast); writer.value(point.saturation); writer.endArray(); } writer.endObject(); } @Override public void deSerializeRepresentation(JsonReader sreader) throws IOException { sreader.beginObject(); Vector points = new Vector(); while (sreader.hasNext()) { String name = sreader.nextName(); if (name.startsWith(LINE_NAME)) { int pointNo = Integer.parseInt(name.substring(LINE_NAME.length())); sreader.beginArray(); Band p = new Band(); p.mask = false; sreader.hasNext(); p.xPos1 = sreader.nextInt(); sreader.hasNext(); p.yPos1 = sreader.nextInt(); sreader.hasNext(); p.xPos2 = sreader.nextInt(); sreader.hasNext(); p.yPos2 = sreader.nextInt(); sreader.hasNext(); p.brightness = sreader.nextInt(); sreader.hasNext(); p.contrast = sreader.nextInt(); sreader.hasNext(); p.saturation = sreader.nextInt(); sreader.hasNext(); sreader.endArray(); points.add(p); } else { sreader.skipValue(); } } mBands = points; trimVector(); mCurrentBand = mBands.get(0); sreader.endObject(); } }