3

好的,我已经搜索过了,我似乎找不到我需要的答案。:-(

这是我正在做的事情以及我需要做的事情。我有一个 UIImageView,我可以使用 UIPanGestureRecognizer、UIRotationGestureRecognizer 和 UIPinchGestureRecognizer 进行转换,一切都很好。当需要将这些转换保存到我的 PhotoAlbum 时,问题就来了。结果不是我所期待的。到目前为止,这是我正在使用的代码(虽然非常不完整)

-(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.size);
     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);


}

通过这种方法,我可以保存图像,但是坐标很差。我可以看到我所做的任何缩放都可以。我看到了我的旋转,但它似乎是倒退的,而且平移已经消失了。

坐标都是错误的,对于我的生活,我无法弄清楚出了什么问题。我承认我是 Objective-C 的新手,而且我以前从未使用过 Quartz 2D,而且我对变换矩阵的理解有限。我确实知道我的转换不是在图像数据本身上,因为试图将图像保存出来而不应用这个上下文什么都不做。所以请任何人都可以直接告诉我吗?

4

2 回答 2

2

您通常希望在扩展之前进行翻译。

您已经翻转了坐标系,但仍分配了旧的 x 和 y 值。我认为你应该有:

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

face此代码中未定义该对象。如果它关闭,则其他所有内容都将关闭。如果它是一个属性,您应该使用self.face参考表来确保它被正确访问。

我建议最后执行比例变换。

如果这些都不起作用。注释掉除一个变换之外的所有变换,看看那个变换是否有效。然后添加其他人,直到它失败。

于 2010-12-01T21:19:45.743 回答
0

如果您在 UIView 中对图像进行转换、缩放然后渲染图层,这种工作会容易得多。以后省去各种麻烦。

就像是:

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();

您会注意到我翻转了图像渲染的坐标系,但将其恢复为 UIView.layer 渲染的原始坐标系。

希望这可以帮助

于 2010-12-07T07:24:17.297 回答