Reprint Please specify source:http://blog.csdn.net/allen315410/article/details/39932689
Implementation of the 1.3D Gallery
We know that the Android system has provided us with a "container"--gallery to show the picture, but the effect of this Gallery display is flat and the dynamic effect is not strong. Here, we do a custom gallery component, to achieve the 3D effect of the picture display, think it should be good, first look:
How to achieve this 3D effect gallery? First, the analysis,
1, display the picture, the system comes with gallery component, can extend the effect that we need based on this gallery component.
2, the display effect requires 3D imaging.
3, the image below the display needs to show the image of the reflection.
4, the reflection of the display image needs to add "mask" effect.
OK, the question is OK, let's solve it by ourselves! The code is not much, directly on the code good.
Package Com.example.gallery.view;import Android.content.context;import Android.graphics.camera;import Android.graphics.matrix;import Android.util.attributeset;import Android.view.view;import Android.view.animation.transformation;import Android.widget.gallery;import android.widget.imageview;@ Suppresswarnings ("deprecation") public class Customgallery extends Gallery {/** Gallery center point */private Int Gallerycenterpoint = 0;/** Camera Object */private camera camera;public customgallery (context context, AttributeSet Attrs) {Super (context, attrs);//Start getchildstatictransformationsetstatictransformationsenabled (true); camera = new camera ();} /** * This method is also called when the width and height of the gallery is changed, the first time the width and height of the gallery is computed, or @Overrideprotected void onsizechanged (int w, int h, int oldw, int o LDH) {//TODO auto-generated method Stubsuper.onsizechanged (W, H, OLDW, OLDH); gallerycenterpoint = Getgallerycenterpoint ();} /** * Returns the transform effect of the gallery item's sub-shape * * @param t * Specifies the transform effect of the current item */@Overrideprotected Boolean getchildstatictransfor MatIon (View Child, transformation t) {int viewcenterpoint = Getviewcenterpoint (child);//center of view int rotateangle = 0;//rotation angle degrees, default to 0//if the center point of the view is not equal to the gallery center, both sides of the picture need to calculate the rotation angle if (viewcenterpoint! = gallerycenterpoint) {//Gallery center Point-View Center point = Difference int diff = gallerycenterpoint-viewcenterpoint;//Difference/width of picture = ratio float scale = (float) diff/(float) child.getwidth ();//ratio * Maximum rotation angle = rotation angle of the final view (maximum rotation angle is 50 degrees) Rotateangle = (int) (scale *), if (Math.Abs (Rotateangle) > 50) {///when final angle of rotation) max. Rotation angle degrees, to change to 50 or -50rotateangle = rotateangle > 0? 50:-50;}} Before setting the transform effect, the transformation effect of the previous item in transformation needs to be cleared t.clear (); T.settransformationtype (Transformation.type_matrix); The type of the transform effect is set to the matrix type Starttransformationitem ((ImageView) child, Rotateangle, T); return true;} /** * Set the effect of the transform * * @param IV * Gallery ITEM * @param rotateangle * Rotation angle * @param t * transform Object */private void Starttransformationitem (ImageView IV, int rotateangle,transformation t) {camera.save ();//Save status int ABSR Otateangle = Math. ABS (Rotateangle);//1. Enlarge the effect (the picture in the middle is bigger than the picture on both sides) camera.translate (0, 0, 100f); Position the camera int zoom = -250 + (Absrotateangle * 2), camera.translate (0, 0, zoom);//2. Transparency (the picture in the middle is fully displayed with a certain amount of transparency on both sides) int alpha = (int ) (255-(Absrotateangle * 2.5)); Iv.setalpha (alpha);//3. Rotate (the picture in the middle does not have a rotation angle, as long as the picture in the middle does not have a rotation angle) camera.rotatey (rotateangle); Matrix matrix = T.getmatrix (); Transforms the matrix and adds the transform effect to the matrix Camera.getmatrix (matrix); The matrix is given to the camera object, and the camera object converts the effect added above into a matrix to be added to the Matrixes object Matrix.pretranslate (-iv.getwidth ()/2,-iv.getheight ()/2) ; Matrix Pre-Multiply Matrix.posttranslate (Iv.getwidth ()/2, Iv.getheight ()/2); Matrix followed by Camera.restore (); Restore previously saved state}/** * Get center point of Gallery * * @return */private int getgallerycenterpoint () {return this.getwidth ()/2;} /** * Gets the center point of the item on the View * * @param v * @return */private int getviewcenterpoint (View v) {return v.getwidth ()/2 + V.getlef T (); Half of the picture width + picture distance from screen left}}
There are comments in the code, you can look at the comments to understand the code, I am here to say how to consider, it seems particularly troublesome! Here is also a very important concept-the matrix, this I stay below to explain, look down.
Tool classes to get pictures:
Package Com.example.gallery.view;import Java.lang.ref.softreference;import Java.util.hashtable;import Android.content.res.resources;import Android.graphics.bitmap;import Android.graphics.bitmap.config;import Android.graphics.porterduff.mode;import Android.graphics.porterduffxfermode;import Android.graphics.shader.tilemode;import Android.graphics.bitmapfactory;import Android.graphics.Canvas;import Android.graphics.lineargradient;import Android.graphics.matrix;import Android.graphics.paint;import Android.util.log;public class Imageutil {private static final String TAG = "Imageutil";/** cache collection */private static Hashtable <integer, softreference<bitmap>> mimagecache//= new Hashtable<integer, SoftReference<Bitmap> > ();/** * Returns a processed picture by ID * * @param res * @param resID * @return */public static Bitmap Getimagebitmap (Resources res, int ResID) {//Go to the collection first to see if the current ResID has taken the picture, if the collection has, the description has been taken, directly using the picture in the collection to return softreference<bitmap> reference = Mimagecache.get (ResID); if (Reference! = NULL) {Bitmap Bitmap = Reference.get (), if (Bitmap! = null) {//Take log.i from memory (TAG, "Fetch from Memory"); return Bitmap;}} If the collection does not, call Getinvertimage to get a picture, you need to keep one in the collection, and finally return the current picture log.i (TAG, "reload"); Bitmap Invertbitmap = Getinvertbitmap (res, ResID);//Save a copy in the collection to get Mimagecache.put directly in the collection on next fetch (ResID, new SoftReference <Bitmap> (Invertbitmap)); return invertbitmap;} /** * According to the image ID, get the picture after processing * * @param resID * @return */public static Bitmap Getinvertbitmap (Resources res, int resID) {// 1. Get the original bitmap Sourcebitmap = Bitmapfactory.decoderesource (res, ResID);//2. Generate reflection image Matrix M = new Matrix (); Picture Matrix M.setscale (1.0f, -1.0f); Let the picture be inverted by matrix Bitmap Invertbitmap = Bitmap.createbitmap (Sourcebitmap, 0,sourcebitmap.getheight ()/2, Sourcebitmap.getwidth (), Sourcebitmap.getheight ()/2, M, false);//3. Two pictures synthesize a picture bitmap Resultbitmap = Bitmap.createbitmap (Sourcebitmap.getwidth (), (int) (Sourcebitmap.getheight () * 1.5 + 5), config.argb_8888); Canvas canvas = new canvas (RESULTBITMAP); Specify an artboard Canvas.drawbitmap for the composition picture (Sourcebitmap, 0f, 0f, NULL); Draw the original picture on top of the canvas Canvas.drawbitmap (Invertbitmap, 0f, Sourcebitmap.getheight () + 5, NULL); Draw the reflection image below the canvas//4. Add Matte effect paint paint = new paint ();//Set the color of the matte, using a linear gradient lineargradient shader = new LinearGradient (0,sou Rcebitmap.getheight () + 5, 0, Resultbitmap.getheight (), 0X70FFFFFF, 0X00FFFFFF, Tilemode.clamp);p Aint.setshader ( shader);//Set Mode: Mask, take intersection paint.setxfermode (new Porterduffxfermode (mode.dst_in)); Canvas.drawrect (0, Sourcebitmap.getheight () + 5,sourcebitmap.getwidth (), Resultbitmap.getheight (), paint); return resultbitmap;}}
This tool class is to get the whole picture, including the reflection and mask effect of the image, see the comments! What needs to be explained here is that if you avoid oom, this is a more complex concept, not one or two words can be clear, Android loading image is easy to deal with Oom, of course, avoid oom way There are many, I in this is using the memory cache mechanism to avoid, Even use Java to provide us with a good "soft reference" to solve. Next, this is how to reference the gallery component.
<relativelayout xmlns:android= "http://schemas.android.com/apk/res/android" xmlns:tools= "http// Schemas.android.com/tools " android:layout_width=" match_parent " android:layout_height=" Match_parent " android:background= "@android: Color/black" > <com.example.gallery.view.customgallery android: Id= "@+id/customgallery" android:layout_width= "match_parent" android:layout_height= "Match_parent" > </com.example.gallery.view.CustomGallery></RelativeLayout>
Package Com.example.gallery;import Com.example.gallery.view.customgallery;import Com.example.gallery.view.imageutil;import Android.app.activity;import Android.graphics.bitmap;import Android.graphics.drawable.bitmapdrawable;import Android.os.bundle;import Android.view.view;import Android.view.viewgroup;import Android.widget.baseadapter;import Android.widget.gallery.layoutparams;import Android.widget.imageview;public class Mainactivity extends Activity {/** Image resource array */private int[] imageresids;@ overrideprotected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview ( R.layout.activity_main) Imageresids = new int[]{//r.drawable.imgres_01,//r.drawable.imgres_02,//R.drawable.imgres _03,//r.drawable.imgres_04,//r.drawable.imgres_05,//r.drawable.imgres_06,//r.drawable.imgres_07,// R.drawable.imgres_08,//r.drawable.imgres_01,//r.drawable.imgres_02,//r.drawable.imgres_03,//R.drawable.imgres_ //r.drawable.imgres_05,//r.drawable.imgres_06,//r.drawabLE.IMGRES_07,//r.drawable.imgres_08//}; Customgallery customgallery = (customgallery) Findviewbyid (r.id.customgallery); Imageadapter adapter = new ImageAdapter (); Customgallery.setadapter (adapter);} public class Imageadapter extends Baseadapter {@Overridepublic int getcount () {//TODO auto-generated method Stubreturn im Ageresids.length;} @Overridepublic Object getItem (int position) {//TODO auto-generated method Stubreturn imageresids[position];} @Overridepublic long Getitemid (int position) {//TODO auto-generated method Stubreturn position;} @Overridepublic view GetView (int position, view Convertview, ViewGroup parent) {//TODO auto-generated method Stubimagevie W imageview;if (Convertview! = null) {ImageView = (ImageView) Convertview;} else {imageView = new ImageView (mainactivity.t His);} Bitmap Bitmap = Imageutil.getimagebitmap (Getresources (), imageresids[position]); Bitmapdrawable drawable = new Bitmapdrawable (bitmap);d Rawable.setantialias (true); Anti-aliasing imageview.setimagedrawable (drawable); LAyoutparams params = new Layoutparams (UP), imageview.setlayoutparams (params); return imageView;}}
=========================================== Gorgeous split-line =============================================
Matrix Foundation of 2.Android
UI development process, we often need to deal with the image, common such as maps, some more complex, such as location transformation, rotation, filter effects, and so on, the following is a brief introduction to the image processing of some basic knowledge and principles.
1 Basic Concepts
For the image processing, the most commonly used data structure is bitmap, it contains a picture of all the data, which data including those content? In short, it is composed of lattice and color values, so-called lattice is a concept is a width * height of the matrix, each element corresponds to a pixel of the picture, that is, the dot matrix holds the picture's spatial location information, and the color value is ARGB, respectively, corresponding to the transparency, red, green, Blue These four channel components, each channel is defined with 8 bits, so a color value is an int integer that can represent 256*256*256 color values.
There are a few constants we use in Android: argb_8888, argb_4444, rgb_565. These constants are actually telling the system how to deal with the color values of the picture, for example, argb_8888 is to tell the system transparency, R, G, b in the color value of 8bit respectively, when the color value of 32bit, so that the definition can represent the most color values, picture quality is also the best; argb_ 4444 is each channel with 4bit, so that the color value is only 16bit, save space, but can only represent 16*16*16 color, that is, the picture is lost a lot of color information; The color value of the rgb_565 type is also 16bit, but it discards the transparency information. can represent 32*64*32 color values.
2 Color matrix
The color matrix is a 5*4 matrix that is used to manipulate image color values. Define the color matrix and color values as follows:
Perform the following matrix operations:
The result R is a 4*1 matrix, which is the new color value, and the values for each channel in R are as follows:
R ' = a*r + b*g + c*b + d*a + E;
G ' = f*r + g*g + h*b + i*a + j;
B ' = k*r + l*g + m*b + n*a + o;
A ' = p*r + q*g + r*b + s*a + t;
This may seem abstract, it is difficult to understand the relationship between the color matrix and the result R directly, we assume that the color matrix values are as follows:
Then the result is:
R ' = r;
G ' = g;
B ' = b;
A ' = A;
In other words, the new color value is the same as the original! In another example, the color matrix is given the following values:
The result is:
R ' = r + 100;
G ' = g + 100;
B ' = b;
A ' = A;
In the new color value, the red channel value and the green channel value are increased by 100 respectively, and the picture is yellowing (because r + G = Yellow).
From the above examples we can easily understand the meaning of each component in the color matrix (each column):
The first line determines the red,
The second row determines the green,
The third line determines the blue,
Row four determines the transparency,
The fifth column is the offset of the color.
At this point we should be able to understand how to change the color values of each component by the color matrix.
Here is a piece of code for Android that handles the picture as a yellowing effect:
public static Bitmap Testbitmap (Bitmap Bitmap) { Bitmap output = Bitmap.createbitmap (Bitmap.getwidth (), Bitmap.getheight (), config.rgb_565); Canvas canvas = new canvas (output); Paint paint = new paint (); ColorMatrix cm = new ColorMatrix (); Float[] Array = {1,0,0,0,100, 0,1,0,0,100, 0,0,1,0,0, 0,0,0,1,0}; Cm.set (array); Paint.setcolorfilter (new Colormatrixcolorfilter (cm)); Canvas.drawbitmap (bitmap, 0, 0, paint); return output; }
3 Coordinate transformation matrix
The operation of the picture in addition to the processing of color values, the most commonly used is the transformation of spatial coordinates, the common effect of translation, rotation, stretching, etc., which is actually done by a matrix. The coordinate transformation matrix is a 3*3 matrix, which is able to convert the coordinate value into a new coordinate value by a matrix multiplication with a similar (x,y,1) coordinate value, which is calculated as follows:
The result is:
X ' =a*x+b*y+c
Y ' =d*x+e*y+f
As with the color matrix, if the coordinate transformation matrix is as follows, the new coordinate value x, y increases by 50, that is, each point of the picture is shifted (50,50) distance, that is, the picture is shifted to the (50,50) coordinates.
If the coordinate transformation matrix is as follows, all x and y coordinates are increased by twice times, which means that the image is magnified twice times, and the other scaling effect is similar.
More complicated is the rotation effect, a rotation transformation matrix is as follows:
The result is x ' = xcosθ–ysinθ and y ' = xsinθ+ ycosθ, the effect of which is to rotate the θ angle counterclockwise around the origin.
Here is a sample code for Android that pans the picture, that is, the cropped effect, and other effects can be modified by reference to the corresponding coordinate transformation matrix:
public static Bitmap Test1bitmap (Bitmap Bitmap) { Bitmap output = Bitmap.createbitmap (Bitmap.getwidth (), Bitmap.getheight (), config.rgb_565); Canvas canvas = new canvas (output); Paint paint = new paint (); Matrix cm = new matrix (); Float[] Array = {1,0,50, 0,1,50, 0,0,1}; Cm.setvalues (array); Canvas.drawbitmap (bitmap, CM, paint); return output; }
Here are a few common transformation matrices:
1. Rotate
the transformation formula for turning the θ angle counterclockwise around the origin is X ' = xcosθ? ysinθ and y ' = xsinθ+ ycosθ
2. Zooming
The length of the transform is enlarged by X ' =scale*x;y ' =scale*y respectively.
3. Shear
4. Reflection
5. Positive projection
Android image Matrix is definitely more than these, this is a very complex knowledge, related to the University of mathematics courses, can understand the university linear algebra matrix knowledge, to learn the image matrix under the Android has a good help, here confined to space, I only do a simple basic explanation, basic can understand, You can use it, if you want to learn more, please check the information below to download the information I uploaded to the CSDN repository today.
Android Image Matrix Basics and detailed information
Please download the source code here
Android Custom Controls--3d gallery and image matrix