开发者

How to save an image using UIImageWriteToSavedPhotosAlbum after it is transformed

Ok I have searched all over and I can't not seem to find the answer I need. :-(

Here is what I am doing and what I need to happen. I have a UIImageView that I am able to transfrom using UIPanGestureRecognizer, UIRotationGestureRecognizer, and UIPinchGestureRecognizer all that works great. The problem comes when it is time to save those transfomations to my PhotoAlbum. The results are not what i am expecting. So far here is the code that i am using (al-be-it very incomplete)

-(IBAction)saveface:(id)sender
{     

     static int kMaxResolution = 640;

     CGImageRef imgRef = face.image.CGImage;
     CGFloat width = CGImageGetWidth(imgRef);
     CGFloat height = CGImageGetHeight(imgRef);

     CGRect bounds = CGRectMake(0, 0, width, height);
     if (width > kMaxResolution || height > kMaxResolution) {
          CGFloat ratio = width/height;
          if (ratio > 1) {
               bounds.size.width = kMaxResolution;
               bounds.size.height = bounds.size.width / ratio;
          } else {
               bounds.size.height = kMaxResolution;
               bounds.size.width = bounds.size.height * ratio;
          }
     }


     UIGraphicsBeginImageContext(bounds.si开发者_如何学Goze);
     CGContextRef context = UIGraphicsGetCurrentContext();

     CGContextScaleCTM(context, 1, -1);
     CGContextTranslateCTM(context, 0, -height);


     NSLog(@"SAVE  TX:%f TY:%f A:%f B:%f C:%f D:%f", face.transform.tx, face.transform.ty, face.transform.a,face.transform.b,face.transform.c,face.transform.d);
     CGFloat x = face.transform.tx;
     CGFloat y = face.transform.ty;

     CGContextTranslateCTM (context, x,-y);

     CGContextConcatCTM(context, face.transform);

     CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width, height), imgRef);
     UIImage *imageCopy = UIGraphicsGetImageFromCurrentImageContext();

     UIGraphicsEndImageContext();


     UIImageWriteToSavedPhotosAlbum(imageCopy, self, nil, nil);


}

From this method I am able to save the image however the coordinates are way off. I can see any scaling I did that works ok. I see my rotation but it seems to be backwards and the paning is WAY off.

The coords are all wrong and for the life of me I can't figure out what is wrong. I admit I am new to Objective-C and I have never used Quartz 2D before and my understanding of the transform matrixes is limited. I do understand that my transformations are not on the image data itself as trying to save the image out right with out applying this context to it does nothing. So please can anyone set me straight on this?


You generally want to translate before you scale.

You've flipped your coordinate system but you still assign the old x and y values. I think you should have:

 CGFloat y = face.transform.tx;
 CGFloat x = face.transform.ty;

The face object is not defined in this code. If it is off, everything else will be off. If it is a property you should use the self.face reference form to make sure it is accessed properly.

I would recommend performing the scale transform last.

If none of this works. Comment out all but one transform and see if that single transform works. Then add the others in until it fails.


This kind of work is much easier if you the image in a UIView, transform, scale and then render the layer. It saves all kinds of hassle later.

Something like:

CGSize vscaledSize = myOriginalImage.size;

//add in the scaled bits of the view
//scaling
CGFloat wratio = vscaledSize.width/self.pictureView.frame.size.width;
CGFloat vhightScaled = self.pictureView.frame.size.height * wratio;
vscaledSize.height = vhightScaled;

CGFloat hratio = vscaledSize.height/self.pictureView.frame.size.height;

//create context
UIGraphicsBeginImageContext(myOriginalImage.size);
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSaveGState(context); //1 original context

// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, vscaledSize.height);
CGContextScaleCTM(context, 1.0, -1.0);

//original image
CGContextDrawImage(context, CGRectMake(0,0,vscaledSize.width,vscaledSize.height), myOriginalImage.CGImage);

CGContextRestoreGState(context);//1  restore to original;

//scale context to match view size
CGContextSaveGState(context); //1 pre-scaled size
CGContextScaleCTM(context, wratio, hratio);

//render 
[self.pictureView.layer renderInContext:context];

CGContextRestoreGState(context);//1  restore to pre-scaled size;

UIImage *exportImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

You'll notice that I flip the coord system for the image render, but restore it to the original coordinate system for the UIView.layer render.

Hope this helps

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜