Custom Controls for Android graphics and images (demo: Scratch, human bypass, and image cache)
Overview:
This part covers the android custom View, custom attributes, and comprehensive Android Image Processing Applications: Bitmap, Path, Matrix, and Canvas.
Image human bypass and how to cache human bypass images are very likely to be used on a daily basis, and image scraping is not useless.
The demo below describes a scratch routine, which involves how to customize the control attributes and how to store the processed images. The annotations are very detailed. Just read the annotations.
Result demonstration:
Result After saving the file: <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Vc3Ryb25nPjxiciAvPg0KPGltZyBhbHQ9 "here write picture description" src = "http://www.bkjia.com/uploads/allimg/150922/0416005R3-1.gif" title = "\"/>
DemoCreate a custom View:
Public class MyBitMapViewSec extends View {private int width; private int height; private float x; private float y; private float old_x; private float old_y; private Paint mPaintCircle; private Paint mPaintRect; private Bitmap mBitmap; private Bitmap mBitmapGround; private Matrix matrix; private Path mPath; private Canvas mCanvasBm; public MyBitMapViewSec (Context context) {super (context);} // pu Blic MyBitMapViewSec (Context context, AttributeSet attrs) {// attrs is the set of all attributes of this View in the xml layout. super (context, attrs ); // parse attrs to final TypedArray a = context. obtainStyledAttributes (attrs, R. styleable. selfish); // get the content of the self_background attribute of the custom View in xml, and forcibly convert it to BitmapDrawable type BitmapDrawable dra = (BitmapDrawable). getDrawable (R. styleable. selfish_self_background); if (dra! = Null) {// If dra is not empty, the dra is assigned to mBitmapGround = dra. getBitmap ();} In else {// mBitmapGround, an image is imported into mBitmapGround = BitmapFactory. decodeResource (getResources (), R. mipmap. qingxin);} // obtain the content in the self_paintWidth attribute of the custom View in xml. If no value is available, the default value is 30 float paintWidth =. getDimension (R. styleable. selfish_self_paintWidth, 30); mPaintCircle = new Paint (); mPaintCircle. setColor (Color. YELLOW); mPaintRect = new Paint (); // XOR: overlapping and overlapped parts are not displayed; DST_OVER: overlapping parts are not displayed; the SRC_OVER overlapping part only displays the porterduxfermode mode = new porterduxfermode (PorterDuff. mode. XOR); mPaintRect. setXfermode (mode); mPaintRect. setStrokeWidth (paintWidth); mPaintRect. setStrokeJoin (Paint. join. ROUND); // set the style mPaintRect of the join part. setStrokeCap (Paint. cap. ROUND); // set the middle part style: Circular mPaintRect. setStyle (Paint. style. FILL_AND_STROKE); mPath = new Path (); matrix = new Matrix () ;}@ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {super. onMeasure (widthMeasureSpec, heightMeasureSpec); width = getDefaultSize (rows (), widthMeasureSpec); height = getDefaultSize (rows (), heightMeasureSpec); setMeasuredDimension (width, height ); // This sentence cannot be placed in the constructor because the values of width and height mBitmap = Bitmap have not been obtained. createBitmap (width, height, Bitmap. config. ARGB_8888); mCanvasBm = new Canvas (mBitmap); // customize a Canvas. The canvas material is a Bitmap object.} @ Override protected void onDraw (Canvas) {super. onDraw (canvas); matrix. reset (); // The following two rows are used to enlarge the image and draw the matrix. postScale (float) width/mBitmapGround. getWidth (), (float) height/mBitmapGround. getHeight (); canvas. drawBitmap (mBitmapGround, matrix, null); // draw a mask mCanvasBm. drawRect (, width, height, mPaintCircle); // draw the path because the mPaintRect mode is PorterDuff. mode. XOR, so the overlapping part will not be displayed when drawing, so as to display the bottom image to mCanvasBm. drawPath (mPath, mPaintRect); // This step indicates that the content drawn by mCanvasBm on mBitmap is drawn as a canvas. drawBitmap (mBitmap, 0, 0, null);} @ Override public boolean onTouchEvent (MotionEvent event) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: y = event. getY (); x = event. getX (); // CW is the Path direction: clockwise // mPath. addCircle (x, y, 50, Path. direction. CW); mPath. moveTo (x, y); // re-draw, that is, re-call the onDraw () method invalidate (); // update the old_x and old_y values old_x = x; old_y = y; return true; case MotionEvent. ACTION_MOVE: y = event. getY (); x = event. getX (); // move mPath to the previous position mPath. moveTo (old_x, old_y); // draw the besell curve, (x + old_x)/2, (y + old_y)/2) as the control point, (x, y) as the end point mPath. quadTo (x + old_x)/2, (y + old_y)/2, x, y); invalidate (); old_x = x; old_y = y; return true ;} return super. onTouchEvent (event );}}
If android studio is used, create a new file under the res/value path and name it randomly. Here I am called selfish. The content is as follows:
In the above Code: attr represents the attributes of my custom View. I have added two attributes here. declare-styleabl is used to add custom attributes to the custom control, it is an attribute set.
This file and its attributes will be used in the layout file. before using it, you must declare:
Xmlns: selfish = "http://schemas.android.com/apk/res-auto"
Then I can call two attributes in the selfish property set in my custom View -- com. example. administrator. selfdefinedview. widget. MyBitMapViewSec:
* Selfish: self_background = "@ mipmap/aa"
Selfish: self_paintWidth = "100dp "*
Write the following code in the main function to cache the image in the View:
Public class TimerActivity extends Activity {private Button mButtonResolve; private MyBitMapViewSec myBitMapViewSec; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_timer); mButtonResolve = (Button) findViewById (R. id. button_resolve); myBitMapViewSec = (MyBitMapViewSec) findViewById (R. id. my_slider); mButtonResolve. s EtOnClickListener (new View. onClickListener () {@ Override public void onClick (View v) {// enable myBitMapViewSec for caching. setDrawingCacheEnabled (true); // getDrawingCache (true) gets the current myBitMapViewSec cache Bitmap bitmap = myBitMapViewSec. getDrawingCache (true); // obtain the path File = new file(environment.getexternalstoragedirectory(,,system.currenttimemillis(%%%.jpg) for storing the bitmap file; if (! File. exists () {try {file. createNewFile ();} catch (IOException e) {e. printStackTrace () ;}try {// convert bitmap to JPEG format to keep the original size written to the file bitmap. compress (Bitmap. compressFormat. JPEG, 100, new FileOutputStream (file);} catch (FileNotFoundException e) {e. printStackTrace ();}}});}}
How can I write image human bypass codes? It is very simple. You only need to modify the onDraw () method, draw the beauty chart to the canvas you declared, and then use the canvas that comes with the onDraw () method to change the final position, the bottom of the sliding frequency screen is yellow. The Code is as follows:
Protected void onDraw (Canvas canvas) {super. onDraw (canvas); // draw a canvas. drawRect (0, 0, width, height, mPaintCircle); // draw the path because the mPaintRect mode is PorterDuff. mode. XOR, so the overlapping part will not be displayed when drawing, so as to display the bottom image to matrix. reset (); // The following two rows are used to enlarge the image and draw the matrix. postScale (float) width/mBitmapGround. getWidth (), (float) height/mBitmapGround. getHeight (); mCanvasBm. drawBitmap (mBitmapGround, matrix, null); mCanvasBm. drawPath (mPath, mPaintRect); // This step indicates that the content drawn by mCanvasBm on mBitmap is drawn as a canvas. drawBitmap (mBitmap, 0, 0, null );}
Result demonstration: