1 2 package com.android.gallery3d.filtershow.imageshow; 3 4 import android.content.Context; 5 import android.content.res.Resources; 6 import android.graphics.Bitmap; 7 import android.graphics.BitmapFactory; 8 import android.graphics.BitmapShader; 9 import android.graphics.Canvas; 10 import android.graphics.Color; 11 import android.graphics.Matrix; 12 import android.graphics.Paint; 13 import android.graphics.PorterDuff; 14 import android.graphics.PorterDuffColorFilter; 15 import android.graphics.RectF; 16 import android.graphics.Shader; 17 import android.graphics.drawable.Drawable; 18 import android.graphics.drawable.NinePatchDrawable; 19 import android.os.Handler; 20 import android.util.AttributeSet; 21 import android.view.MotionEvent; 22 23 import com.android.gallery3d.R; 24 import com.android.gallery3d.filtershow.editors.EditorDraw; 25 import com.android.gallery3d.filtershow.filters.FilterDrawRepresentation; 26 import com.android.gallery3d.filtershow.filters.ImageFilterDraw; 27 28 public class ImageDraw extends ImageShow { 29 30 private static final String LOGTAG = "ImageDraw"; 31 private int mCurrentColor = Color.RED; 32 final static float INITAL_STROKE_RADIUS = 40; 33 private float mCurrentSize = INITAL_STROKE_RADIUS; 34 private byte mType = 0; 35 private FilterDrawRepresentation mFRep; 36 private EditorDraw mEditorDraw; 37 private long mTimeout; 38 private Paint mCheckerdPaint = makeCheckedPaint(); 39 private Paint mShadowPaint = new Paint(); 40 private Paint mIconPaint = new Paint(); 41 private Paint mBorderPaint = new Paint(); 42 private Handler mHandler; 43 private FilterDrawRepresentation.StrokeData mTmpStrokData = 44 new FilterDrawRepresentation.StrokeData(); 45 private Bitmap mBitmap; 46 private float mDisplayRound; 47 private float mDisplayBorder; 48 private int DISPLAY_TIME = 500; 49 private Matrix mRotateToScreen = new Matrix(); 50 private Matrix mToOrig; 51 private int mBorderColor; 52 private int mBorderShadowSize; 53 private NinePatchDrawable mShadow; 54 55 Runnable mUpdateRunnable = new Runnable() { 56 @Override 57 public void run() { 58 invalidate(); 59 } 60 }; 61 62 63 public ImageDraw(Context context, AttributeSet attrs) { 64 super(context, attrs); 65 resetParameter(); 66 setupConstants(context); 67 setupTimer(); 68 } 69 70 public ImageDraw(Context context) { 71 super(context); 72 resetParameter(); 73 setupConstants(context); 74 setupTimer(); 75 } 76 77 private void setupConstants(Context context){ 78 Resources res = context.getResources(); 79 mDisplayRound = res.getDimensionPixelSize(R.dimen.draw_rect_round); 80 mDisplayBorder = res.getDimensionPixelSize(R.dimen.draw_rect_border); 81 mBorderShadowSize = res.getDimensionPixelSize(R.dimen.draw_rect_shadow); 82 float edge = res.getDimensionPixelSize(R.dimen.draw_rect_border_edge); 83 84 mBorderColor = res.getColor(R.color.draw_rect_border); 85 mBorderPaint.setColor(mBorderColor); 86 mBorderPaint.setStyle(Paint.Style.STROKE); 87 mBorderPaint.setStrokeWidth(edge); 88 mShadowPaint.setStyle(Paint.Style.FILL); 89 mShadowPaint.setColor(Color.BLACK); 90 mShadowPaint.setShadowLayer(mBorderShadowSize,mBorderShadowSize, 91 mBorderShadowSize,Color.BLACK); 92 mShadow = (NinePatchDrawable) res.getDrawable(R.drawable.geometry_shadow); 93 } 94 95 public void setEditor(EditorDraw editorDraw) { 96 mEditorDraw = editorDraw; 97 } 98 99 public void setFilterDrawRepresentation(FilterDrawRepresentation fr) { 100 mFRep = fr; 101 mTmpStrokData = 102 new FilterDrawRepresentation.StrokeData(); 103 } 104 105 public Drawable getIcon(Context context) { 106 107 return null; 108 } 109 110 @Override 111 public void resetParameter() { 112 if (mFRep != null) { 113 mFRep.clear(); 114 } 115 } 116 117 public void setColor(int color) { 118 mCurrentColor = color; 119 } 120 121 public void setSize(int size) { 122 mCurrentSize = size; 123 } 124 125 public void setStyle(byte style) { 126 mType = (byte) (style % ImageFilterDraw.NUMBER_OF_STYLES); 127 } 128 129 public int getStyle() { 130 return mType; 131 } 132 133 public int getSize() { 134 return (int) mCurrentSize; 135 } 136 137 float[] mTmpPoint = new float[2]; // so we do not malloc 138 @Override 139 public boolean onTouchEvent(MotionEvent event) { 140 if (event.getPointerCount() > 1) { 141 boolean ret = super.onTouchEvent(event); 142 if (mFRep.getCurrentDrawing() != null) { 143 mFRep.clearCurrentSection(); 144 mEditorDraw.commitLocalRepresentation(); 145 } 146 return ret; 147 } 148 if (event.getAction() != MotionEvent.ACTION_DOWN) { 149 if (mFRep.getCurrentDrawing() == null) { 150 return super.onTouchEvent(event); 151 } 152 } 153 154 if (event.getAction() == MotionEvent.ACTION_DOWN) { 155 calcScreenMapping(); 156 mTmpPoint[0] = event.getX(); 157 mTmpPoint[1] = event.getY(); 158 mToOrig.mapPoints(mTmpPoint); 159 mFRep.startNewSection( mTmpPoint[0], mTmpPoint[1]); 160 } 161 162 if (event.getAction() == MotionEvent.ACTION_MOVE) { 163 164 int historySize = event.getHistorySize(); 165 for (int h = 0; h < historySize; h++) { 166 int p = 0; 167 { 168 mTmpPoint[0] = event.getHistoricalX(p, h); 169 mTmpPoint[1] = event.getHistoricalY(p, h); 170 mToOrig.mapPoints(mTmpPoint); 171 mFRep.addPoint(mTmpPoint[0], mTmpPoint[1]); 172 } 173 } 174 } 175 176 if (event.getAction() == MotionEvent.ACTION_UP) { 177 mTmpPoint[0] = event.getX(); 178 mTmpPoint[1] = event.getY(); 179 mToOrig.mapPoints(mTmpPoint); 180 mFRep.endSection(mTmpPoint[0], mTmpPoint[1]); 181 } 182 mEditorDraw.commitLocalRepresentation(); 183 invalidate(); 184 return true; 185 } 186 187 private void calcScreenMapping() { 188 mToOrig = getScreenToImageMatrix(true); 189 mToOrig.invert(mRotateToScreen); 190 } 191 192 private static Paint makeCheckedPaint(){ 193 int[] colors = new int[16 * 16]; 194 for (int i = 0; i < colors.length; i++) { 195 int y = i / (16 * 8); 196 int x = (i / 8) % 2; 197 colors[i] = (x == y) ? 0xFF777777 : 0xFF222222; 198 } 199 Bitmap bitmap = Bitmap.createBitmap(colors, 16, 16, Bitmap.Config.ARGB_8888); 200 BitmapShader bs = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 201 Paint p = new Paint(); 202 p.setShader(bs); 203 return p; 204 } 205 206 private void setupTimer() { 207 mHandler = new Handler(getActivity().getMainLooper()); 208 } 209 210 private void scheduleWakeup(int delay) { 211 mHandler.removeCallbacks(mUpdateRunnable); 212 mHandler.postDelayed(mUpdateRunnable, delay); 213 } 214 215 public Bitmap getBrush(int brushid) { 216 Bitmap bitmap; 217 BitmapFactory.Options opt = new BitmapFactory.Options(); 218 opt.inPreferredConfig = Bitmap.Config.ALPHA_8; 219 bitmap = BitmapFactory.decodeResource(getActivity().getResources(), brushid, opt); 220 bitmap = bitmap.extractAlpha(); 221 222 return bitmap; 223 } 224 225 public Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight, boolean filter) { 226 Matrix m = new Matrix(); 227 m.setScale(dstWidth / (float) src.getWidth(), dstHeight / (float) src.getHeight()); 228 Bitmap result = Bitmap.createBitmap(dstWidth, dstHeight, src.getConfig()); 229 Canvas canvas = new Canvas(result); 230 231 Paint paint = new Paint(); 232 paint.setFilterBitmap(filter); 233 canvas.drawBitmap(src, m, paint); 234 235 return result; 236 237 } 238 239 public void displayDrawLook() { 240 if (mFRep == null) { 241 return; 242 } 243 int color = mTmpStrokData.mColor; 244 byte type = mTmpStrokData.mType; 245 float radius = mTmpStrokData.mRadius; 246 mFRep.fillStrokeParameters(mTmpStrokData); 247 248 if (radius != mTmpStrokData.mRadius) { 249 mTimeout = DISPLAY_TIME + System.currentTimeMillis(); 250 scheduleWakeup(DISPLAY_TIME); 251 } 252 } 253 254 public void drawLook(Canvas canvas) { 255 if (mFRep == null) { 256 return; 257 } 258 int cw = canvas.getWidth(); 259 int ch = canvas.getHeight(); 260 int centerx = cw / 2; 261 int centery = ch / 2; 262 263 // mFRep.fillStrokeParameters(mTmpStrokData); 264 mIconPaint.setAntiAlias(true); 265 mIconPaint.setStyle(Paint.Style.STROKE); 266 float rad = mRotateToScreen.mapRadius(mTmpStrokData.mRadius); 267 268 RectF rec = new RectF(); 269 rec.set(centerx - rad, 270 centery - rad, 271 centerx + rad, 272 centery + rad); 273 mIconPaint.setColor(Color.BLACK); 274 mIconPaint.setStrokeWidth(5); 275 canvas.drawArc(rec, 0, 360, true, mIconPaint); 276 mIconPaint.setColor(Color.WHITE); 277 mIconPaint.setStrokeWidth(3); 278 canvas.drawArc(rec, 0, 360, true, mIconPaint); 279 } 280 281 @Override 282 public void onDraw(Canvas canvas) { 283 super.onDraw(canvas); 284 calcScreenMapping(); 285 if (System.currentTimeMillis() < mTimeout) { 286 drawLook(canvas); 287 } 288 } 289 290 } 291