Combine Uiimageview to move and zoom pictures

Source: Internet
Author: User

iphone ipad Development: Combined with Uiimageview to achieve image movement and zoom for various reasons, the need to implement image viewing in the iphone application, because the iphone screen support multi-touch, so it is to use "gestures" to achieve real-time image zooming and movement. After drawing on the ubiquitous Internet network data, this function is finally realized, the process is as follows. First, realize the original image display (do not scale) new Movescaleimageview class, inherit UIView. Used to load a uiimage. It has two main members, a UIImage object used to specify a memory picture, and a Uiimageview control to display the picture. @interface Movescaleimageview:uiview {uiimage* originimage; uiimageview* ImageView;} -(void) SetImage: (uiimage*) _image; @end @implementation Movescaleimageview-(ID) initWithFrame: (CGRect) frame{if (self =[super Initwithframe:frame]) {Imageview=[[uiimageview alloc]init];[ Self addsubview:imageview];//enables the picture view to support interactive and multi-touch [ImageView Setuserinteractionenabled:yes]; [ImageView Setmultipletouchenabled:yes];} return self;} -(void) dealloc{originimage=nil;imageview=nil;[ Super Dealloc];} -(void) SetImage: (UIImage *) _image{originimage=[[uiimage alloc]initwithcgimage:_image. Cgimage]; [ImageView Setimage:originimage]; [ImageView setframe:cgrectmake (0, 0, _image.size.width, _image.size.height)];//[imageview setneedslayout];} The most important @end is the SetImage method. MovescaleimageviEW is easy to use. Constructs a movescaleimageview in Viewcontroller and then sets its image member with a UIImage object that loads the picture file: uiimage* image=[uiimage imagenamed:@ " Df.jpg "]; Movescaleimageview*filecontent = [[Movescaleimageview alloc]initwithframe:cgrectmake (0, 44, 320, 436)]; [Filecontent Setimage:image]; Because here we do not have any zoom processing of the picture, for the small picture will be located in the upper left corner of the screen, and left blank in other places; for images larger than the screen, the picture is not fully displayed: one, recognition gestures (single touch and multi-touch) to identify gestures (gesture), You must respond to the notification method for 4 gestures (refer to chapter 13th of the Iphone3 Development Basics Tutorial): touchesbegan,touchesmoved,touchesended and touchescancelled. First of all, let's consider a single-touch situation, which is a little bit simpler. In the case of a single touch, moving the finger, the picture in the ImageView can be dragged, so that for the larger picture, we can drag to browse the various parts of the picture, of course, for all the pictures can be displayed at once do not need to drag. Modify the class Movescaleimageview and add some declarations in. h: @interface Movescaleimageview:uiview {uiimage* originimage; uiimageview* ImageView; Cgpoint gesturestartpoint;//When the start of the gesture starts CGFloat offsetx,offsety;//moves when the offset in the X, y direction cgfloat curr_x,curr_y;//The origin coordinates of the picture content being intercepted now} -(void) SetImage: (uiimage*) _image;-(void) Movetox: (cgfloat) x ToY: (cgfloat) y; @end then implement the Touchesbegan and Touchesmoved methods. The Touchesbegan method is relatively simple and records the position of the first touch of the finger. Because any one drag must have a starting point and an end point. -(void) Touchesbegan: (Nsset *) touChes withevent: (uievent *) Event{uitouch *touch=[touches Anyobject];gesturestartpoint=[touch locationInView:self];// NSLog (@ "touch:%f,%f", Gesturestartpoint.x,gesturestartpoint.y);} Then the touchesmoved method of the callback after the finger moves:-(void) touchesmoved: (Nsset *) touches withevent: (uievent *) event{uitouch* touch=[touches Anyobject]; Cgpoint Curr_point=[touch locationinview:self];//calculates the x, and the movement in the Y direction respectively offsetx=curr_point.x-gesturestartpoint.x;offsety= curr_point.y-gesturestartpoint.y;//as long as the distance between either side moves upwards exceeds min_offset, the decision gesture is valid if (FABSF (OffsetX) >= min_offset| | FABSF (OffsetY) >=min_offset) {[Self movetox:offsetx toy:offsety];gesturestartpoint.x=curr_point.x; Gesturestartpoint.y=curr_point.y;}} Here we make a simple judgment that only the finger is moved over a certain pixel (Min_offset constant) before it is recognized as a drag gesture and the Movetox method is called. In this method, it is necessary to constantly update the coordinates of the finger movement, because this is a continuous process. -(void) Movetox: (cgfloat) x ToY: (cgfloat) y{//calculates the moved rectangle, Origin x, y coordinates, rectangle width height cgfloat destx,desty,destw,desth;curr_x=destx= Curr_x-x;curr_y=desty=curr_y-y;destw=self.frame.size.width;desth=self.frame.size.height;if (destX<0) {// Left border out of bounds processing curr_x=destx=0;} if (desty<0) {//upper border out-of-bounds processing curr_y=desty=0;} if (destx+destw>originimage.size.width) {//Right border out of bounds processing CURR_X=DESTX=ORIGINIMAGE.SIZE.WIDTH-DESTW;} if (desty+desth>originimage.size.height) {//Right border out of bounds processing curr_y=desty=originimage.size.height-desth;} Create a rectangular box for this famecgrect rect = CGRectMake (Destx, Desty, Self.frame.size.width, self.frame.size.height); imageview.image=[ UIImage Imagewithcgimage:cgimagecreatewithimageinrect ([Originimage cgimage], rect)];} In this method, we take a special approach: capturing part of a large image and displaying the interception in ImageView. The reason I do this is because it is the simplest and easiest way to achieve it. I've consulted several implementations on the web, and I've found that I basically need to use the quartz2d API, and it's much more complex to implement. It was finally inspired by the CCTV system (imagine that the security staff moved the scene by moving the mouse over the camera). We designed a rectangular frame to use as a simulated lens: CGRect lensrect; Setting the size of the lens a global variable is also designed to record the zoom magnification during image scaling: cgfloat scale; Zoom scale when tracking to the finger movement, let the "lens" do the reverse movement (why is the inverse motion?) Because we're simulating the "drag" effect, not the "track" effect, the two are the opposite. The image in the lens is captured into the ImageView by the UIImage Imagewithcgimage:cgimagecreatewithimageinrect method. In this way, the move operation is actually converted to the position of the computed rectangle box. Of course, we also have to do a good job of boundary judgment, otherwise, when the rectangle is outside the original range of the image, there will be distorted scaling phenomenon. Next look at how to recognize multi-touch. Recognizing single-touch and multi-touch is actually very simple, judging Touchesbegan's touches parameter's Count property to:-(Void) Touchesbegan: (Nsset*) touches withevent: (Uievent *) event{if ([touches count]==2) {//Recognize two-point touch and record distance between two points nsarray* Twotouches=[touches Allobjects];originspace=[self spacetopoint:[[twotouches objectatindex:0] locationinview:self] FromPoint:[[ Twotouches Objectatindex:1] locationinview:self];} else if ([touches count]==1) {Uitouch *touch=[touches anyobject];gesturestartpoint=[touch locationinview:self];}} In the above method, we determine whether it is a single touch and separate processing according to the count of touches. For 2-point touch, we recorded the distance between the two fingers and recorded it in the global cgfloat variable originspace. The Spacetopoint method is a simple function that calculates the distance between 2 points:-(CGFloat) using a 3-point function from middle School, Spacetopoint: (cgpoint) First frompoint: (cgpoint) two{// Calculate the distance between two points float x = first.x–two.x;float y = First.y–two.y;return sqrt (x * x + y * y);} In a two-point touch, 2 gestures need to be identified: outward kneading, inward kneading. Usually the former causes the image to be enlarged, while the latter makes the image smaller. In the Touchesmoved method, this process:-(void) touchesmoved: (Nsset *) touches withevent: (Uievent *) event{if ([touches count]==2) { nsarray* twotouches=[touches allobjects]; CGFloat currspace=[self spacetopoint:[[twotouches objectatindex:0] locationinview:self] FromPoint:[[twoTouches Objectatindex:1] Locationinview:Self]]; If touch a finger first, then touch another finger, then trigger touchesmoved method instead of Touchesbegan method//At this time originspace should be 0, we want to correctly set its value to the current detected distance, otherwise it may cause 0 except the error if ( originspace==0) {originspace=currspace;} if (FABSF (currspace-originspace) >=min_offset) {//two fingers move more than min_offset, recognized as gesture "pinch" cgfloat s=currspace/originspace; Calculate the scale [self scaleto:s];}} else if ([touches count]==1) {... (Part of the Code omitted)}} It is simple to determine whether it is a valid pinch (we have defined a constant min_offset for this), and if so, the quotient that calculates the length of the finger's effective movement and the two-finger spacing at the beginning of the gesture as a scale. Then call the Scaleto method:-(void) Scaleto: (cgfloat) x{scale*=x;//scaling limit: >=0.1,<=10scale= (scale<0.1)? 0.1:scale;scale= ( SCALE&GT;10)? 10:scale;//Reset ImageView frame[self movetox:0 TOY:0];} Here, we limit the value of scale to between 0.1 and 10 (of course, you can define this threshold as a constant) to prevent the user from "pinching" the image without restriction. It then invokes a move operation in situ, which is the previous MoveTo method. However for support of the indented picture movement, this method was changed by us:-(void) Movetox: (cgfloat) x ToY: (cgfloat) Y{cgpoint point=cgpointmake (x, y);//reset lens [self Resetlens:point];imageview.image=[uiimage Imagewithcgimage:cgimagecreatewithimageinrect ([OriginImage CGImage], Lensrect)]; [ImageView setframe:cgrectmake (0, 0, Lensrect.size.width*scale, vlensRect.size.height*scale)];} More of the code was moved to another method resetlens:-(void) Resetlens: (cgpoint) point{//set the lens size and position cgfloat x,y,width,height;//=========== Lens Initial Size =========width=self.frame.size.width/scale;height=self.frame.size.height/scale;//=========== Resize mirror size must not exceed image actual size ==========if (width>originimage.size.width) {width=originimage.size.width;} if (height>originimage.size.height) {height=originimage.size.height;} Calculates the position of the lens movement (equal to scale) x=lensrect.origin.x-point.x/scale;y=lensrect.origin.y-point.y/scale;//left border out-of-bounds processing x= (x<0)? 0:x;/ /upper border out-of-bounds processing y= (y<0)? 0:y;//right border out of bounds x= (x+width>originimage.size.width)? originimage.size.width-width:x;//lower border out-of-bounds processing y= (y+height>originimage.size.height) originimage.size.height-height:y;//lens zoom Lensrect=cgrectmake (x, y, Width, height);} This code is slightly different from the code in the original Movetox method, mainly to increase the introduction of the scale variable, because in the zoom mode, the movement of the lens is reduced by the scaling factor. The entire code is not difficult to understand. In this way, the big picture after the "pinch" operation can be fully displayed on the screen (the original 2nd picture is now an Apple Computer): Of course, the small image "pinch" to enlarge into a large picture is also possible. You can also see different parts of the picture by moving your finger.

Combining Uiimageview for moving and zooming pictures

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.