1dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford/*
2dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * Copyright (C) 2015 The Android Open Source Project
3dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford *
4dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * Licensed under the Apache License, Version 2.0 (the "License");
5dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * you may not use this file except in compliance with the License.
6dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * You may obtain a copy of the License at
7dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford *
8dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford *      http://www.apache.org/licenses/LICENSE-2.0
9dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford *
10dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * Unless required by applicable law or agreed to in writing, software
11dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * distributed under the License is distributed on an "AS IS" BASIS,
12dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * See the License for the specific language governing permissions and
14dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * limitations under the License.
15dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford */
16dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
17dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordpackage rs.example.android.com.healingbrush;
18dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
19dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.app.Activity;
20dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.content.Intent;
21dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.database.Cursor;
22dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Bitmap;
23dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.BitmapFactory;
24dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Matrix;
25dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.drawable.Drawable;
26dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.net.Uri;
27dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.os.AsyncTask;
28dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.os.Bundle;
29dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.os.Environment;
30dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.provider.OpenableColumns;
31dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.support.v8.renderscript.RenderScript;
32dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.util.Log;
33dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.view.MotionEvent;
34dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.view.View;
35dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.widget.ImageView;
36dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.widget.Toast;
37dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
38dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport com.example.android.rs.sample.ScriptC_find_region;
39dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport com.example.android.rs.sample.ScriptC_healing;
40dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
41dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport java.io.File;
42dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport java.io.FileNotFoundException;
43dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport java.io.InputStream;
44dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
45dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordpublic class MainActivity extends Activity {
46dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    private static final String TAG = "MainActivity";
47dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    ImageView mImgView;
48dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    DrawView mDrawView;
49dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    Matrix mMatrix = new Matrix();
50dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    Matrix mInverseMatrix = new Matrix();
51dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    Bitmap mDisplayedImage;
52dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    Bitmap mImage2;
53dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    RenderScript mRs;
54dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    ScriptC_healing mHealingScript;
55dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    ScriptC_find_region mFindRegion;
56dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    private float mZoom = 0.8f;
57dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    float mYOffset = 0;
58dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    float mXOffset = 0;
59dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    RunScript mRunScript = null;
60dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    private String mImagePath;
61dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    private String mImageName;
62dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    private Region mLastRegion;
63dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
64dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    @Override
65dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    protected void onCreate(Bundle savedInstanceState) {
66dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        super.onCreate(savedInstanceState);
67dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        setContentView(R.layout.activity_main);
68dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mImgView = (ImageView) findViewById(R.id.imageview);
69dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mDrawView = (DrawView) findViewById(R.id.overlay);
70dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mDrawView.setImageView(mImgView);
71dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mRs = RenderScript.create(this.getBaseContext());
72dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mHealingScript = new ScriptC_healing(mRs);
73dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mFindRegion = new ScriptC_find_region(mRs);
74dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
75dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mImgView.setOnTouchListener(new View.OnTouchListener() {
76dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float[] imgPoint = new float[2];
77dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float[] imgMoveList = new float[100];
78dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            boolean mPanZoomDown = false;
79dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
80dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float mCenterDownX;
81dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float mCenterDownY;
82dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float mDistDown;
83dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float mDownXOffset;
84dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float mDownYOffset;
85dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            float mDownZoom;
86dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            boolean inMultiTouch = false;
87dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
88dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            @Override
89dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            public boolean onTouch(View v, MotionEvent event) {
90dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                int action = event.getAction();
91dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                float x = event.getX();
92dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                float y = event.getY();
93dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                imgPoint[0] = x;
94dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                imgPoint[1] = y;
95dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                int sw = mImgView.getWidth();
96dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                int sh = mImgView.getHeight();
97dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                int iw = mImgView.getDrawable().getIntrinsicWidth();
98dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                int ih = mImgView.getDrawable().getIntrinsicHeight();
99dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                switch (action) {
100dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    case MotionEvent.ACTION_DOWN:
101dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        Log.v(TAG, "ACTION_DOWN " + event.getPointerCount());
102dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
103dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        break;
104dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    case MotionEvent.ACTION_UP:
105dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        Log.v(TAG, "ACTION_UP " + event.getPointerCount());
106dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
107dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        break;
108dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    case MotionEvent.ACTION_MOVE:
109dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        Log.v(TAG, "ACTION_MOVE " + event.getPointerCount());
110dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        break;
111dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                }
112dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                if (event.getPointerCount() > 1) {
113dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    inMultiTouch = true;
114dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                }
115dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                if (event.getPointerCount() == 2) {
116dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    float x1 = event.getX(0);
117dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    float y1 = event.getY(0);
118dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    float x2 = event.getX(1);
119dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    float y2 = event.getY(1);
120dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    if (mPanZoomDown) {
121dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        float dx = (x1 + x2) / 2 - mCenterDownX;
122dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        float dy = (y1 + y2) / 2 - mCenterDownY;
123dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        float zoom = (float) Math.hypot(x1 - x2, y1 - y2);
124dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mZoom = zoom * mDownZoom / mDistDown;
125dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
126dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        float scale = mZoom * Math.min(sw / (float) iw, sh / (float) ih);
127dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mXOffset = mDownXOffset + 2 * (dx / (sw - scale * iw));
128dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mYOffset = mDownYOffset + 2 * (dy / (sh - scale * ih));
129dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        if (Math.abs(mXOffset) > 1) {
130dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mXOffset = Math.signum(mXOffset);
131dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        }
132dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        if (Math.abs(mYOffset) > 1) {
133dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mYOffset = Math.signum(mYOffset);
134dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        }
135dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    } else {
136dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mDrawView.undo();
137dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mPanZoomDown = true;
138dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mCenterDownX = (x1 + x2) / 2;
139dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mCenterDownY = (y1 + y2) / 2;
140dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mDistDown = (float) Math.hypot(x1 - x2, y1 - y2);
141dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mDownXOffset = mXOffset;
142dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mDownYOffset = mYOffset;
143dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mDownZoom = mZoom;
144dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    }
145dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                } else {
146dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    if (mPanZoomDown) {
147dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        mPanZoomDown = false;
148dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    }
149dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                }
150dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                if (!mPanZoomDown) {
151dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    switch (action) {
152dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        case MotionEvent.ACTION_DOWN:
153dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mInverseMatrix.mapPoints(imgPoint);
154dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mDrawView.clearDrawables();
155dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mDrawView.downPoint(imgPoint);
156dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mDrawView.invalidate();
157dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
158dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            break;
159dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        case MotionEvent.ACTION_UP:
160dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            if (inMultiTouch && event.getPointerCount() == 1) {
161dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                inMultiTouch = false;
162dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            } else {
163dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                mInverseMatrix.mapPoints(imgPoint);
164dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                mDrawView.upPoint(imgPoint);
165dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                mDrawView.invalidate();
166dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            }
167dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
168dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            break;
169dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        case MotionEvent.ACTION_MOVE:
170dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
171dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            int size = event.getHistorySize();
172dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            size = Math.min(size, imgMoveList.length / 2);
173dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            for (int i = 0; i < size; i++) {
174dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                imgMoveList[i * 2] = event.getHistoricalX(size - i - 1);
175dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                imgMoveList[i * 2 + 1] = event.getHistoricalY(size - i - 1);
176dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            }
177dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mInverseMatrix.mapPoints(imgMoveList, 0, imgMoveList, 0, size);
178dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            if (!inMultiTouch) {
179dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                mDrawView.movePoint(imgMoveList, size);
180dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                                mDrawView.invalidate();
181dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            }
182dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            break;
183dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    }
184dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                }
185dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                updateMatrix();
186dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
187dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                return true;
188dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            }
189dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        });
190dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
191dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
192dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        new AsyncLoad().execute();
193dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
194dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
195dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    void updateMatrix() {
196dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        int sw = mImgView.getWidth();
197dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        int sh = mImgView.getHeight();
198dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        int iw = mImgView.getDrawable().getIntrinsicWidth();
199dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        int ih = mImgView.getDrawable().getIntrinsicHeight();
200dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
201dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
202dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mMatrix.reset();
203dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        float scale = mZoom * Math.min(sw / (float) iw, sh / (float) ih);
204dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mMatrix.postTranslate((1 + mXOffset) * (sw - iw * scale) / 2,
205dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                (1 + mYOffset) * (sh - ih * scale) / 2);
206dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mMatrix.preScale(scale, scale);
207dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        boolean ret = mMatrix.invert(mInverseMatrix);
208dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        if (!ret) {
209dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            Log.e(TAG, "Fail to invert");
210dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
211dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mImgView.setImageMatrix(mMatrix);
212dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mImgView.invalidate();
213dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mDrawView.invalidate();
214dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford     }
215dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
216dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    void getScreenCoord(float[] point) {
217dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        Matrix matrix = mImgView.getImageMatrix();
218dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
219dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    class AsyncLoad extends AsyncTask<Void, Void, Void> {
220dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
221dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        protected Void doInBackground(Void... regions) {
222dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            Intent intent = getIntent();
223dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
224dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            if (intent != null) {
225dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                File folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
226dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                mImagePath = folder.getPath();
227dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
228dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                String s = intent.getType();
229dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                if (s != null && s.indexOf("image/") != -1) {
230dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    Uri data = (Uri) intent.getParcelableExtra(Intent.EXTRA_STREAM);
231dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    mImageName = "edit"+data.getLastPathSegment(); // TODO the wrong way to do this
232dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
233dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    if (data != null) {
234dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        InputStream input = null;
235dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        try {
236dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            input = getContentResolver().openInputStream(data);
237dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            mDisplayedImage = BitmapFactory.decodeStream(input);
238dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
239dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            return null;
240dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        } catch (FileNotFoundException e) {
241dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                            e.printStackTrace();
242dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                        }
243dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
244dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    }
245dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                }
246dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            }
247dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
248dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            getLocalImage();
249dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            return null;
250dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
251dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
252dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        @Override
253dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        protected void onPostExecute(Void s) {
254dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mImgView.setImageBitmap(mDisplayedImage);
255dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            Log.v(TAG, "BITMAP SIZE = " + mDisplayedImage.getWidth() + "," +
256dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                    mDisplayedImage.getHeight());
257dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
258dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            updateMatrix();
259dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
260dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
261dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    void getLocalImage() {
262dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
263dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        File folder;
264dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        folder = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
265dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mImagePath = folder.getPath();
266dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        File[] files = folder.listFiles();
2677aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang        if (files != null) {
2687aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang            Log.v(TAG, "files" + files.length);
2697aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang            for (int i = 0; i < files.length; i++) {
2707aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                Log.v(TAG, "[" + i + "]=" + files[i].getAbsolutePath());
2717aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                if (files[i].getName().toLowerCase().endsWith(".jpg")) {
2727aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                    mDisplayedImage = BitmapFactory.decodeFile(files[i].getAbsolutePath());
2737aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                    mImagePath = files[i].getParentFile().getAbsolutePath();
2747aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                    mImageName = files[i].getName();
2757aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                    return;
2767aa770ae0f0f962d538e6627adc67954a9b56a8fMiao Wang                }
277dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            }
278dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
279dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
280dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mDisplayedImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.bugs);
281dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mImageName = "bugs";
282dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
283dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
284dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    public void heal(View v) {
285dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        mLastRegion = mDrawView.getRegion(mDisplayedImage);
286dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        if (mRunScript == null) {
287dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mRunScript = new RunScript();
288dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mRunScript.execute(mLastRegion);
289dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
290dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
291dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
292dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    public void undo(View v) {
293dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        if (mImage2 != null) {
294dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mLastRegion.undo(mImage2);
295dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mDrawView.invalidate();
296dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
297dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
298dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
299dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    public void save(View v) {
300dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        String name = mImageName;
301dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        if (name.indexOf(".") > 0) {
302dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            name = name.substring(0, name.lastIndexOf(".")) + "_e";
303dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
304dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        MediaStoreSaver.save(mImage2,
305dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                mImagePath,
306dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                name,
307dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                this,
308dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                MediaStoreSaver.TYPE_JPG);
309dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        Toast.makeText(this, "Saved " + name, Toast.LENGTH_SHORT).show();
310dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
311dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
312dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    class RunScript extends AsyncTask<Region, String, String> {
313dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        Drawable d;
314dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
315dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        protected String doInBackground(Region... regions) {
316dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            d = regions[0].findMatch(mFindRegion, mRs, mDisplayedImage);
317dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
318dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            if (mImage2 == null) {
319dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford                mImage2 = mDisplayedImage.copy(Bitmap.Config.ARGB_8888, true);
320dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
321dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            }
322dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            regions[0].heal(mHealingScript, mRs, mImage2, mImage2);
323dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
324dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            return "";
325dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
326dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
327dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        @Override
328dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        protected void onPostExecute(String s) {
329dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            super.onPostExecute(s);
330dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mDrawView.addDrawable(d);
331dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mDrawView.invalidate();
332dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mImgView.setImageBitmap(mImage2);
333dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford            mRunScript = null;
334dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford        }
335dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford    }
336dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford
337dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford}
338