This function can help you to achieve, in the picture of random smear, can be used for SNS products.
The drawing itself is simple, but it's a bit of a hassle to implement the exact (position, zoom) drawings that you specify on the picture.
Here's how to implement the process and principles:
UI composition
This UI, seemingly simple, or somewhat complex, the following needs a bottom chart, above a transparent picture control, when drawing to synchronize two control deformation.
UI Hierarchy Diagram
Why, do I need a canvas image to be consistent with back? Because, Canvas image will be painted on the Canvas, it is Canvas host, that is, ImageView was turned into a canvas, the original ImageView content will be erased. If you only have back image then once the canvas is open, you can't see anything.
The Magic matrix.
The ImageView control is one of the most commonly used Android controls and is used primarily for picture display. Basically all of the high-level languages have similar controls. But there's one thing that makes him a miracle, and that's The matrix. With the matrix we can achieve the image translation, amplification, rotation, distortion and other commonly used effects. The matrix itself is a 9*9, which holds the translation coordinates, the magnification factor, the sin/cos angle value. We can use Getmatrix () to get a matrix of IV, or to set its value by SetMatrix ().
What's the use of the stuff on the top? Imagine when we open a photo album and look at a picture, you can touch, pan, or enlarge the picture. We, to the above drawing, first Canvas image into Canvas, but, Canvas image has not changed. You must ensure that at least two IMG controls have the same distortion, otherwise you cannot align the painted coordinates. This time, or when the back image changes, Canvas image immediately synchronized operation, or, most of the Canvas on the time, synchronized deformation. The former scheme is not necessary and decisively uses the latter one. This time you have to ask, how do I get the deformation parameters of IV? IV provides a number of ways to separate the acquisition and setting of some kind of deformation, at that time toss for a long time, not only cumbersome, but not to achieve the effect. By this time, the matrix on the top came in handy. At the time, no one was so happy to tell me this.
Coordinate mapping
The above finished the transformation of the graphics, and now finally can paint the top. But a picture, you will find a problem, not to draw the specified position. What is the problem? coordinate system offset. The (0,0) point defaults to the upper-left corner of the screen. But, think about when our picture is not a screen, when very small, canvas's coordinate system in what position? I draw a point in the screen (0,0) coordinates, and a point appears on the canvas, even if the two positions are far apart.
At this point, we need to map two coordinate systems and align the coordinate systems by offsetting. How much is the offset? It's time to use the translate value of the matrix. So we can know the image in the coordinate system offset, along with how you can move the coordinates are accurate alignment.
Copy Code code as follows:
Private HashMap getimageviewineersize (ImageView IV) {
HashMap size=new HashMap ();
Get the transformation matrix of image in ImageView
Matrix m = Iv.getimagematrix ();
Float[] values = new FLOAT[10];
M.getvalues (values);
The transformation matrix of image in the drawing process, from which the scaling factor of the X and Y directions is obtained
float SX = values[0];
Float sy = values[4];
Calculates the width of the image that is actually drawn on the screen
Size.put ("ScaleX", 1/SX);
Size.put ("ScaleY", 1/sy);
Size.put ("OffsetX", values[2]); The value of the x-axis translate
Size.put ("OffsetY", values[5]);
return size;
}
where Width=backimage.getdrawable (). getbounds (). width ();
You'll find a scalex, what's this for? Let's assume that the picture is now scaled to exactly the width of the screen, and the actual width of the picture is 960px. But we draw a point in the x=480px, where should this point be shown in the picture? Our intention is to draw a point at the end of the picture, that is, the x=960px, but now it has run to 480, obviously does not meet the requirements. At this point, you need to multiply the top of the ScaleX.
Final code for drawing lines:
Copy Code code as follows:
/* Draw line according to two point coordinates
*startx, stopx the place where the touch event begins and ends
*offsetx, for the picture on the x axis of the displacement value
*scalex, the inverse of the zoom value for the picture on the x axis
*/
if ((starty-offsety) >=0&& (stopy-offsety) >=0)
Canvas.drawline ((STARTX-OFFSETX) *scalex, (starty-offsety) *scaley, (Stopx-offsetx) *scalex, (StopY-offsetY) *scaleY, pen);
Note
The actual size of the ImageView is equal to the size of the screen and the actual size of the canvas is determined by the actual size of the picture.
The ImageView is easy to get, but the picture inside it is variable, how to get its current size? Use (original size * scaling factor).
Merge
The final step is to merge two layers into one picture. The reference code is as follows:
Copy Code code as follows:
/**
* Combine two bitmap for one piece
* @param background
* @param foreground
* @return Bitmap
*/
public static Bitmap Combinebitmap (Bitmap background, Bitmap foreground) {
if (background = = null) {
return null;
}
int bgwidth = Background.getwidth ();
int bgheight = Background.getheight ();
int fgwidth = Foreground.getwidth ();
int fgheight = Foreground.getheight ();
Bitmap Newmap = Bitmap.createbitmap (Bgwidth, Bgheight, config.argb_8888);
Canvas Canvas = new Canvas (NEWMAP);
Canvas.drawbitmap (background, 0, 0, NULL);
Canvas.drawbitmap (foreground, (bgwidth-fgwidth)/2,
(bgheight-fgheight)/2, NULL);
Canvas.save (Canvas.all_save_flag);
Canvas.restore ();
return newmap;
}//end of Combinebitmap
By canvas to merge and change the size of the bitmap, because the size of two layers, the position is exactly the same, so coordinate alignment (0,0) point can be.
If, without the previous work, you are difficult to accurately merge the pictures.