ImageFilterRedEye.java revision cc93226fc364a50de3a1479c0912e9af1854b666
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
23cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardimport com.android.gallery3d.filtershow.imageshow.GeometryMetadata;
2490b1d251973bfa748d435896fc277cb4024451adJohn Hoford
25cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardimport java.util.Vector;
2690b1d251973bfa748d435896fc277cb4024451adJohn Hoford
27cc93226fc364a50de3a1479c0912e9af1854b666nicolasroardpublic class ImageFilterRedEye extends ImageFilter {
28cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    private static final String LOGTAG = "ImageFilterRedEye";
29cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    private Vector<RedEyeCandidate> mCandidates = null;
3090b1d251973bfa748d435896fc277cb4024451adJohn Hoford
31cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public ImageFilterRedEye() {
32cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        mName = "Red Eye";
3390b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
3490b1d251973bfa748d435896fc277cb4024451adJohn Hoford
3590b1d251973bfa748d435896fc277cb4024451adJohn Hoford    @Override
3690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    public ImageFilter clone() throws CloneNotSupportedException {
3790b1d251973bfa748d435896fc277cb4024451adJohn Hoford        ImageFilterRedEye filter = (ImageFilterRedEye) super.clone();
38cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates != null) {
39cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            int size = mCandidates.size();
40cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            filter.mCandidates = new Vector<RedEyeCandidate>();
41cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            for (int i = 0; i < size; i++) {
42cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                filter.mCandidates.add(new RedEyeCandidate(mCandidates.elementAt(i)));
43cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
44cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
4590b1d251973bfa748d435896fc277cb4024451adJohn Hoford        return filter;
4690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
4790b1d251973bfa748d435896fc277cb4024451adJohn Hoford
48cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    @Override
49cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public boolean isNil() {
50cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates != null && mCandidates.size() > 0) {
51cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
52cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
53cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        return true;
54cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
55cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
56cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    @Override
57cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public boolean same(ImageFilter filter) {
58cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        boolean isRedEyeFilter = super.same(filter);
59cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (!isRedEyeFilter) {
60cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
61cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
62cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        ImageFilterRedEye redEyeFilter = (ImageFilterRedEye) filter;
63cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (redEyeFilter.mCandidates == null && mCandidates == null) {
64cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return true;
65cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
66cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (redEyeFilter.mCandidates == null || mCandidates == null) {
67cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
68cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
69cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (redEyeFilter.mCandidates.size() != mCandidates.size()) {
70cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            return false;
71cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
72cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        int size = mCandidates.size();
73cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        for (int i = 0; i < size; i++) {
74cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate c1 = mCandidates.elementAt(i);
75cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate c2 = redEyeFilter.mCandidates.elementAt(i);
76cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            if (!c1.equals(c2)) {
77cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                return false;
78cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
79cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
80cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        return true;
81cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
82cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
83cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public Vector<RedEyeCandidate> getCandidates() {
84cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates == null) {
85cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates = new Vector<RedEyeCandidate>();
86cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
87cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        return mCandidates;
88cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
89cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
90cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public void addRect(RectF rect, RectF bounds) {
91cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates == null) {
92cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates = new Vector<RedEyeCandidate>();
93cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
94cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        Vector<RedEyeCandidate> intersects = new Vector<RedEyeCandidate>();
95cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        for (int i = 0; i < mCandidates.size(); i++) {
96cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate r = mCandidates.elementAt(i);
97cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            if (r.intersect(rect)) {
98cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                intersects.add(r);
99cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
100cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
101cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        for (int i = 0; i < intersects.size(); i++) {
102cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            RedEyeCandidate r = intersects.elementAt(i);
103cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            rect.union(r.mRect);
104cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            bounds.union(r.mBounds);
105cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates.remove(r);
106cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
107cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        mCandidates.add(new RedEyeCandidate(rect, bounds));
108cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
109cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
110cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    public void clear() {
111cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates == null) {
112cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            mCandidates = new Vector<RedEyeCandidate>();
113cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
114cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        mCandidates.clear();
115cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    }
116cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard
117cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard    native protected void nativeApplyFilter(Bitmap bitmap, int w, int h, short[] matrix);
11890b1d251973bfa748d435896fc277cb4024451adJohn Hoford
119a9f280f938b5fd5891c5cfe0999f8f1d4945d7a1nicolasroard    @Override
1201b72a2f1124610b8050dbbdff9f1bb548199fd2eJohn Hoford    public Bitmap apply(Bitmap bitmap, float scaleFactor, boolean highQuality) {
12190b1d251973bfa748d435896fc277cb4024451adJohn Hoford        int w = bitmap.getWidth();
12290b1d251973bfa748d435896fc277cb4024451adJohn Hoford        int h = bitmap.getHeight();
123cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        short[] rect = new short[4];
12490b1d251973bfa748d435896fc277cb4024451adJohn Hoford
125cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        if (mCandidates != null && mCandidates.size() > 0) {
126cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            for (int i = 0; i < mCandidates.size(); i++) {
127cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                RectF r = new RectF(mCandidates.elementAt(i).mRect);
128cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                GeometryMetadata geo = getImagePreset().mGeoData;
129cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                Matrix originalToScreen = geo.getOriginalToScreen(true,
130cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                        getImagePreset().getImageLoader().getOriginalBounds().width(),
131cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                        getImagePreset().getImageLoader().getOriginalBounds().height(),
132cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                        w, h);
133cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                originalToScreen.mapRect(r);
134cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.left < 0) {
135cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.left = 0;
136cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
137cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.left > w) {
138cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.left = w;
139cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
140cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.top < 0) {
141cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.top = 0;
142cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
143cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.top > h) {
144cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.top = h;
145cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
146cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.right < 0) {
147cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.right = 0;
148cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
149cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.right > w) {
150cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.right = w;
151cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
152cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.bottom < 0) {
153cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.bottom = 0;
154cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
155cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                if (r.bottom > h) {
156cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                    r.bottom = h;
157cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                }
158cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[0] = (short) r.left;
159cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[1] = (short) r.top;
160cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[2] = (short) r.width();
161cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                rect[3] = (short) r.height();
162cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard                nativeApplyFilter(bitmap, w, h, rect);
163cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard            }
164cc93226fc364a50de3a1479c0912e9af1854b666nicolasroard        }
1651b72a2f1124610b8050dbbdff9f1bb548199fd2eJohn Hoford        return bitmap;
16690b1d251973bfa748d435896fc277cb4024451adJohn Hoford    }
16790b1d251973bfa748d435896fc277cb4024451adJohn Hoford}
168