Canvas also provides the cropping function.
The cropping function is completed by a series of clip... methods and quickreject methods provided by canvas. As mentioned above, the mutable bitmap inside the canvas is actually available for plotting. Canvas is more like a layer. We can only draw items on the layer above it.
1. first introduce the region class
Region indicates a closed area on the canvas layer.
/** Constructor */Public region () // create an empty Region Public region (region Region) // copy the range public region (rect R) of a region) // create public region (INT left, int top, int right, int bottom) for the region of a rectangle. // create a rectangle area./** a series of Set methods, these set methods, similar to the preceding Construction Method */Public void setempty () {public Boolean set (Region region) Public Boolean set (rect R) Public Boolean set (INT left, int top, int right, int bottom)/* adds a path to a region. Only this method is available. The clip parameter indicates the region of the entire region, crop the area in the path range */Public Boolean setpath (Path, Region clip) // construct a region using the specified path and crop range/** several judgment methods */Public native Boolean isempty (); // determine whether the region is empty public native Boolean isrect (); // whether it is a matrix public native Boolean iscomplex (); // whether it is a combination of multiple Matrices/** a series of getbound methods, returns a region boundary */Public rect getbounds () Public Boolean getbounds (rect R) Public path getboundarypath () public Boolean getboundarypath (Path)/** a series of checks to determine whether a vertex exists or not */Public native Boolean contains (int x, int y ); // whether it contains a certain point public Boolean quickcontains (rect R) // whether it contains a matrix public native Boolean quickcontains (INT left, int top, int right, int bottom) // does not contain a matrix public Boolean quickreject (rect R) // does not intersection with this matrix public native Boolean quickreject (INT left, int top, int right, int bottom ); // whether or not the public native Boolean quickreject (Region RGN) is not intersecting with the matrix ); // whether it does not intersect with this matrix/** several translation transformation methods */Public void translate (INT dx, int Dy) Public native void translate (INT dx, int dy, region DST); Public void Scale (float scale) // hidepublic native void Scale (float scale, Region DST ); // hide/** a series of combination methods */public final Boolean Union (rect R) Public Boolean OP (rect R, OP) {public Boolean OP (INT left, int top, int right, int bottom, OP) Public Boolean OP (Region region, OP) Public Boolean OP (rect, Region region, OP)
The above is almost all the region APIs. It is easy to understand and mainly describes the last group of region combinations. The combination is the current region and another region combination, which can be combined in different op modes.
OP is an enumeration defined in the region class.
Suppose region1 is used to combine region2 public Enum op {difference (0), // The final region is Intersect (1) in different regions of region1 and region2 ), // The final region is the region Union (2) in which region1 and region2 intersect, // The final region is the region XOR (3) in which region1 and region2 are combined ), // The final region is reverse_difference (4) outside the intersection of region1 and region2, // The final region is the region Replace (5) of region2 and region1 ); // The final region is region2}
Apidemo provides an example of the combination at the end.
Android also provides a regioniterator to iterate all matrices in region. You can use this class to obtain all matrices of a region. Relatively simple.
2. What is cropping?
Crop clip, that is, crop the canvas layer. What we draw can only be displayed within the range of the cropping area.
@ Override protected void ondraw (canvas) {paint = new paint (); canvas. save (); canvas. cliprect (New rect (100,100,300,300); canvas. drawcolor (color. blue); // The rect of the cropping area changes to blue canvas. drawrect (New rect (100,100,), paint); // The canvas cannot be displayed outside the cropped area. drawcircle (150,150, 50, paint); // within the cropping area, the canvas is displayed. restore ();}
Cropping is not like matrix transformation. Its Coordinates relative to mutable bitmap do not change. Therefore, painting beyond the cropping area is not displayed.
3. Save and roll back Cropping
As mentioned earlier, canvas. Save () and canvas. Restore () are effective not only for matrix, but also for clip.
4. Cropping Method
Canvas provides three cropping methods:
1. The most basic cliprect, cropping a rectangle
2. clippath: crop the range included in the path. The range included in the path is valid only when it is not empty.
3. clipregion.
Region is an encapsulation of region combinations. However, the biggest difference between cliprect and clippath is as follows:
Note that unlike clipRect() and clipPath() which transform their arguments by the current matrix, clipRegion() assumes its argument is already in the coordinate system of the current layer's bitmap, and so not transformation is performed.
Unlike cliprect and clippath, the current matrix must be used for transformation. Clipregion is not converted. That is to say, the matrix of the canvas has no effect on clipregion.
Paint paint = new paint (); canvas. scale (0.5f, 0.5f); canvas. save (); canvas. cliprect (New rect (100,100,200,200); // the actual size of the cropping area is 50*50 canvas. drawcolor (color. red); canvas. restore (); canvas. drawrect (New rect (100,100,), paint); // the actual size of the rectangle is 50*50 canvas. clipregion (new region (New rect (300,300,400,400); // the actual size of the cropping area is 100*100 canvas. drawcolor (color. black );
As you can see, the canvas transformation does not work for clipregion.
Examples of combinations in apidemo:
public class Clipping extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new SampleView(this)); } private static class SampleView extends View { private Paint mPaint; private Path mPath; public SampleView(Context context) { super(context); setFocusable(true); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setStrokeWidth(6); mPaint.setTextSize(16); mPaint.setTextAlign(Paint.Align.RIGHT); mPath = new Path(); } private void drawScene(Canvas canvas) { canvas.clipRect(0, 0, 100, 100); canvas.drawColor(Color.WHITE); mPaint.setColor(Color.RED); canvas.drawLine(0, 0, 100, 100, mPaint); mPaint.setColor(Color.GREEN); canvas.drawCircle(30, 70, 30, mPaint); mPaint.setColor(Color.BLUE); canvas.drawText("Clipping", 100, 30, mPaint); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.GRAY); canvas.save(); canvas.translate(10, 10); drawScene(canvas); canvas.restore(); canvas.save(); canvas.translate(160, 10); canvas.clipRect(10, 10, 90, 90); canvas.clipRect(30, 30, 70, 70, Region.Op.DIFFERENCE); drawScene(canvas); canvas.restore(); canvas.save(); canvas.translate(10, 160); mPath.reset(); canvas.clipPath(mPath); // makes the clip empty mPath.addCircle(50, 50, 50, Path.Direction.CCW); canvas.clipPath(mPath, Region.Op.REPLACE); drawScene(canvas); canvas.restore(); canvas.save(); canvas.translate(160, 160); canvas.clipRect(0, 0, 60, 60); canvas.clipRect(40, 40, 100, 100, Region.Op.UNION); drawScene(canvas); canvas.restore(); canvas.save(); canvas.translate(10, 310); canvas.clipRect(0, 0, 60, 60); canvas.clipRect(40, 40, 100, 100, Region.Op.XOR); drawScene(canvas); canvas.restore(); canvas.save(); canvas.translate(160, 310); canvas.clipRect(0, 0, 60, 60); canvas.clipRect(40, 40, 100, 100, Region.Op.REVERSE_DIFFERENCE); drawScene(canvas); canvas.restore(); } }}
:
5. A small use of Cropping
Public class clippingregion extends activity {@ override protected void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (New sampleview (this);} private class sampleview extends view {private bitmap mbitmap; private int limitlength = 0; private int width; private int heigth; private Static final int clip_height = 30; private Boolean status = hide; // display or hide the status. The initial value is hide Private Static final Boolean show = true; // display the image Private Static final Boolean hide = false; // hide the image public sampleview (context) {super (context); mbitmap = bitmapfactory. decoderesource (getresources (), R. drawable. image1); limitlength = width = mbitmap. getwidth (); heigth = mbitmap. getheight () ;}@ override protected void ondraw (canvas) {region = new region (); int I = 0; while (I * clip_height <= heigth) {// calculate the clip region if (I % 2 = 0) {region. union (New rect (0, I * clip_height, limitlength, (I + 1) * clip_height);} else {region. union (New rect (width-limitlength, I * clip_height, width, (I + 1) * clip_height) ;} I ++;} canvas. clipregion (region); canvas. drawbitmap (mbitmap, 0, 0, new paint (); If (status = hide) {// If limitlength-= 5 is hidden at this time; If (limitlength <= 0) status = show;} else {// If limitlength + = 5 is displayed at this time; If (limitlength> = width) status = hide;} invalidate ();}}}
The effect is to hide and display images in this way.