ImageFilterRedEye.java revision c649360ce22f0138bfcb745eed585a32eb8570e7
1a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard/*
2a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Copyright (C) 2012 The Android Open Source Project
3a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *
4a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Licensed under the Apache License, Version 2.0 (the "License");
5a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * you may not use this file except in compliance with the License.
6a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * You may obtain a copy of the License at
7a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *
8a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *      http://www.apache.org/licenses/LICENSE-2.0
9a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard *
10a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * Unless required by applicable law or agreed to in writing, software
11a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * distributed under the License is distributed on an "AS IS" BASIS,
12a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * See the License for the specific language governing permissions and
14a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard * limitations under the License.
15a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard */
1690b1d251973bfa748d435896fc277cb4024451adJohn Hoford
1790b1d251973bfa748d435896fc277cb4024451adJohn Hofordpackage com.android.gallery3d.filtershow.filters;
1890b1d251973bfa748d435896fc277cb4024451adJohn Hoford
1990b1d251973bfa748d435896fc277cb4024451adJohn Hofordimport android.graphics.Bitmap;
20cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardimport android.graphics.Matrix;
21cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardimport android.graphics.RectF;
2290b1d251973bfa748d435896fc277cb4024451adJohn Hoford
23c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroardimport com.android.gallery3d.R;
24cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardimport com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
2590b1d251973bfa748d435896fc277cb4024451adJohn Hoford
26cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardimport java.util.Vector;
2790b1d251973bfa748d435896fc277cb4024451adJohn Hoford
28cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardpublic class ImageFilterRedEye extends ImageFilter {
29cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    private static final String LOGTAG = "ImageFilterRedEye";
30cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    private Vector<RedEyeCandidate> mCandidates = null;
3190b1d251973bfa748d435896fc277cb4024451adJohn Hoford
32cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public ImageFilterRedEye() {
33cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        mName = "Red Eye";
3490b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
3590b1d251973bfa748d435896fc277cb4024451adJohn Hoford
3690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    @Override
37c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    public int getButtonId() {
38c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard        return R.id.redEyeButton;
39c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    }
40c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard
41c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    @Override
42c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    public int getTextId() {
43c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard        return R.string.redeye;
44c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    }
45c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard
46c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    @Override
47c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    public int getEditingViewId() {
48c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard        return R.id.imageRedEyes;
49c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    }
50c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard
51c649360ce22f0138bfcb745eed585a32eb8570e7nicolasroard    @Override
5290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    public ImageFilter clone() throws CloneNotSupportedException {
5390b1d251973bfa748d435896fc277cb4024451adJohn Hoford        ImageFilterRedEye filter = (ImageFilterRedEye) super.clone();
54cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates != null) {
55cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            int size = mCandidates.size();
56cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            filter.mCandidates = new Vector<RedEyeCandidate>();
57cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            for (int i = 0; i < size; i++) {
58cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                filter.mCandidates.add(new RedEyeCandidate(mCandidates.elementAt(i)));
59cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
60cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
6190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        return filter;
6290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
6390b1d251973bfa748d435896fc277cb4024451adJohn Hoford
64cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    @Override
65cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public boolean isNil() {
66cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates != null && mCandidates.size() > 0) {
67cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
68cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
69cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        return true;
70cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
71cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
72cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    @Override
73cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public boolean same(ImageFilter filter) {
74cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        boolean isRedEyeFilter = super.same(filter);
75cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (!isRedEyeFilter) {
76cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
77cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
78cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        ImageFilterRedEye redEyeFilter = (ImageFilterRedEye) filter;
79cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (redEyeFilter.mCandidates == null && mCandidates == null) {
80cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return true;
81cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
82cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (redEyeFilter.mCandidates == null || mCandidates == null) {
83cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
84cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
85cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (redEyeFilter.mCandidates.size() != mCandidates.size()) {
86cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
87cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
88cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        int size = mCandidates.size();
89cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        for (int i = 0; i < size; i++) {
90cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate c1 = mCandidates.elementAt(i);
91cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate c2 = redEyeFilter.mCandidates.elementAt(i);
92cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            if (!c1.equals(c2)) {
93cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                return false;
94cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
95cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
96cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        return true;
97cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
98cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
99cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public Vector<RedEyeCandidate> getCandidates() {
100cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates == null) {
101cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates = new Vector<RedEyeCandidate>();
102cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
103cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        return mCandidates;
104cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
105cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
106cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public void addRect(RectF rect, RectF bounds) {
107cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates == null) {
108cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates = new Vector<RedEyeCandidate>();
109cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
110cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        Vector<RedEyeCandidate> intersects = new Vector<RedEyeCandidate>();
111cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        for (int i = 0; i < mCandidates.size(); i++) {
112cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate r = mCandidates.elementAt(i);
113cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            if (r.intersect(rect)) {
114cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                intersects.add(r);
115cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
116cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
117cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        for (int i = 0; i < intersects.size(); i++) {
118cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate r = intersects.elementAt(i);
119cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            rect.union(r.mRect);
120cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            bounds.union(r.mBounds);
121cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates.remove(r);
122cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
123cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        mCandidates.add(new RedEyeCandidate(rect, bounds));
124cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
125cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
126cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public void clear() {
127cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates == null) {
128cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates = new Vector<RedEyeCandidate>();
129cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
130cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        mCandidates.clear();
131cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
132cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
133cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short[] matrix);
13490b1d251973bfa748d435896fc277cb4024451adJohn Hoford
135a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard    @Override
1361b72a2f1124610b8050dbbdff9f1bb548199fd2eJohn Hoford    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
13790b1d251973bfa748d435896fc277cb4024451adJohn Hoford        int w = bitmap.getWidth();
13890b1d251973bfa748d435896fc277cb4024451adJohn Hoford        int h = bitmap.getHeight();
139cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        short[] rect = new short[4];
14090b1d251973bfa748d435896fc277cb4024451adJohn Hoford
141cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates != null && mCandidates.size() > 0) {
142cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            for (int i = 0; i < mCandidates.size(); i++) {
143cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                RectF r = new RectF(mCandidates.elementAt(i).mRect);
144cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                GeometryMetadata geo = getImagePreset().mGeoData;
145cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                Matrix originalToScreen = geo.getOriginalToScreen(true,
146cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                        getImagePreset().getImageLoader().getOriginalBounds().width(),
147cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                        getImagePreset().getImageLoader().getOriginalBounds().height(),
148cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                        w, h);
149cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                originalToScreen.mapRect(r);
150cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.left < 0) {
151cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.left = 0;
152cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
153cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.left > w) {
154cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.left = w;
155cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
156cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.top < 0) {
157cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.top = 0;
158cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
159cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.top > h) {
160cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.top = h;
161cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
162cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.right < 0) {
163cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.right = 0;
164cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
165cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.right > w) {
166cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.right = w;
167cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
168cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.bottom < 0) {
169cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.bottom = 0;
170cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
171cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.bottom > h) {
172cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.bottom = h;
173cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
174cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[0] = (short) r.left;
175cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[1] = (short) r.top;
176cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[2] = (short) r.width();
177cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[3] = (short) r.height();
178cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                nativeApplyFilter(bitmap, w, h, rect);
179cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
180cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
1811b72a2f1124610b8050dbbdff9f1bb548199fd2eJohn Hoford        return bitmap;
18290b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
18390b1d251973bfa748d435896fc277cb4024451adJohn Hoford}
184