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.graphics.Bitmap; 20dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Canvas; 21dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Color; 22dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.ColorFilter; 23dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Paint; 24dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Path; 25dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.PathMeasure; 26dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.PorterDuff; 27dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.PorterDuffXfermode; 28dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.Rect; 29dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.RectF; 30dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.graphics.drawable.Drawable; 31dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.support.v8.renderscript.Allocation; 32dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.support.v8.renderscript.Element; 33dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.support.v8.renderscript.RenderScript; 34dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.support.v8.renderscript.Script; 35dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.support.v8.renderscript.Type; 36dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport android.util.Log; 37dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 38dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport com.example.android.rs.sample.ScriptC_find_region; 39dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordimport com.example.android.rs.sample.ScriptC_healing; 40dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 41dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hofordpublic class Region { 42dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford private static final String TAG = "Region"; 43dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford int mCutOffsetX; // image coords of the cut (mPointsXY - mPasteOffX + mCutOffsetX) 44dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford int mCutOffsetY; // image coords of the cut (mPointsXY - mPasteOffY + mCutOffsetY) 45dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 46dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford int[] mPaste; // contains a copy where to paste 47dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 48dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford float[] mPointsXY; // polygon point in original image coordnates 49dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford int numberOfPoints; 50dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 51dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford FindRegion mFindRegion; 52dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford private Bitmap mUndoBitmap; 53dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 54dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford /** 55dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * @param xy A list of xy points that represents the polygon 56dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * @param img The original polygon 57dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford */ 58dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public Region(float[] xy, Bitmap img) { 59dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mPointsXY = xy; 60dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mFindRegion = new FindRegion(mPointsXY, img); 61dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 62dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 63dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Drawable getSourceLocation() { 64dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford final Path path = new Path(); 65dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Rect bounds = mFindRegion.getRoiBounds(); 66dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford for (int i = 0; i < mPointsXY.length; i += 2) { 67dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford if (i == 0) { 68dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford path.moveTo(mPointsXY[i] - bounds.left + mCutOffsetX, 69dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mPointsXY[i + 1] - bounds.top + mCutOffsetY); 70dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } else { 71dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford path.lineTo(mPointsXY[i] - bounds.left + mCutOffsetX, 72dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mPointsXY[i + 1] - bounds.top + mCutOffsetY); 73dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 74dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 75dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford path.close(); 76dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Drawable d = new Drawable() { 77dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Paint paint1 = new Paint(); 78dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Paint paint2 = new Paint(); 79dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 80dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford { 81dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford paint1.setStyle(Paint.Style.STROKE); 82dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford paint2.setStyle(Paint.Style.STROKE); 83dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford paint1.setColor(Color.BLACK); 84dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford paint1.setStrokeWidth(2); 85dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford paint2.setColor(Color.BLUE); 86dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 87dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 88dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 89dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void draw(Canvas canvas) { 90dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford canvas.drawPath(path, paint1); 91dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford canvas.drawPath(path, paint2); 92dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 93dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 94dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 95dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void setAlpha(int alpha) { 96dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 97dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 98dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 99dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void setColorFilter(ColorFilter cf) { 100dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 101dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 102dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 103dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public int getOpacity() { 104dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford return 0; 105dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 106dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford }; 107dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford return d; 108dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 109dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 110dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public Drawable findMatch(ScriptC_find_region findRegion, RenderScript mRs, Bitmap image) { 111dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Rect mRoiBounds = mFindRegion.findMatch(findRegion, mRs, image); 112dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford int cutOffsetX = mFindRegion.getCutOffsetX(); 113dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford int cutOffsetY = mFindRegion.getCutOffsetY(); 114dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford final Path path = new Path(); 115dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford for (int i = 0; i < mPointsXY.length; i += 2) { 116dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford if (i == 0) { 117dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford path.moveTo(mPointsXY[i] - mRoiBounds.left + cutOffsetX, 118dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mPointsXY[i + 1] - mRoiBounds.top + cutOffsetY); 119dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } else { 120dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford path.lineTo(mPointsXY[i] - mRoiBounds.left + cutOffsetX, 121dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mPointsXY[i + 1] - mRoiBounds.top + cutOffsetY); 122dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 123dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 124dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 125dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford path.close(); 126dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 127dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 128dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Drawable d = new Drawable() { 129dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Paint paint = new Paint(); 130dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 131dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford { 132dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford paint.setStyle(Paint.Style.STROKE); 133dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 134dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 135dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 136dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void draw(Canvas canvas) { 137dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford canvas.drawPath(path, paint); 138dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 139dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 140dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 141dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void setAlpha(int alpha) { 142dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 143dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 144dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 145dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void setColorFilter(ColorFilter cf) { 146dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 147dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 148dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford @Override 149dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public int getOpacity() { 150dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford return 0; 151dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 152dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford }; 153dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford return d; 154dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 155dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 156dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Bitmap createMutableBitmap(Bitmap image, int x, int y, int width, int height) { 157dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Bitmap ret = Bitmap.createBitmap(image, x, y, width, height); 158dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford return ret.copy(Bitmap.Config.ARGB_8888, true); 159dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 160dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 161dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford /** 162dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * This function only assumes mPointsXY, mPasteOffX, mPasteOffY 163dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * 164dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * @param healing 165dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * @param rs 166dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford * @param image 167dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford */ 168dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void heal(ScriptC_healing healing, RenderScript rs, Bitmap image, Bitmap output) { 169dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Healing h = new Healing( 170dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mFindRegion.getRoiBounds(), 171dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mPointsXY, 172dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mFindRegion.getCutOffsetX(), 173dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mFindRegion.getCutOffsetY()); 174dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford h.heal(healing, rs, image, output); 175dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford mUndoBitmap = h.getmUndoBitmap(); 176dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 177dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford 178dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford public void undo(Bitmap output) { 179dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Canvas c = new Canvas(output); 180dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford Rect roi; 181dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford roi = mFindRegion.getRoiBounds(); 182dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford c.drawBitmap(mUndoBitmap, roi.left, roi.top, null); 183dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford } 184dbf58070bd1a228fc817ea5ddb5c08fe717aecd2hoford} 185