首先我们需要两个参数来保存重要的信息:
CGFloat m_fScale; // 缩放倍数
CGPoint m_ptStart; // 显示图像块的起始点
m_fScale这个参数很容易理解,你缩放图像,一定得有个缩放倍数,那么就是它了;至于m_ptStart这个参数,我想我可能需要稍微啰嗦两句,来解释一下:当你放大图像时,由于显示区域时固定的,那么你就不可能把整个放大的图像都显示出来,你只能显示某一个块图像,那么这一块图像需要有一个起始点。
好吧,我承认,以上的解释是废话,我们还是来举个例子来说明一下吧。
比如,你的图像是1920 x 1080的分辨率,你放大了2倍,那么整个图像的分辨率就会变成3840 x 2160;如果你把3840 x 2160的图像直接显示出来,那你看到的结果是非但没有放大的效果,还缩小了。因为可显示区域大小是固定的,分辨率越大,显示内容越小。那么如何才能显示放大的图像呢?这时m_ptStart这个参数的作用就显现出来了。假设这个参数的值为(0,0),那么就是说从图像的标准坐标原点开始显示,显示的长度宽度也是固定的(假设是1920 x 1080),那么针对于3840 x 2160这个放大的图像,从(0,0)点开始显示长宽为1920 x 1080的图像块,这样显示的图像就是放大了(因为原本在固定可显示区域要显示1920 x 1080的图像,现在只要显示960 x 540的图像块就可以了)。
这样的例子,不知道是不是所有人都能够理解,还不理解,我也表示无能为力了。
其次,我们需要给一个UIView添加捏合手势识别,假设这个UIView就是我们要在上面显示图像的View,这段代码的作用是,将一个捏合手势添加的View上,并且关联了捏合手势的处理函数gesturePinch。
// m_pTouchView已经关联到了UIView空间上
m_pTouchView.multipleTouchEnabled = YES; // 允许UIView多点触控
UIPinchGestureRecognizer *recongnizerPinch = [[UIPinchGestureRecognizer alloc]init];
[recongnizerPinch addTarget:self action:@select(gesturePinch:)];
[m_pTouchView addGestureRecognizer:recognizerPinch];
这是捏合手势的处理函数,对缩放倍数进行边界检查,并且设置缩放倍数。
-(void)gestruePinch:(id)sender {
UIPinchGestureRecognizer *gesture = (UIPinchGestureRecognizer*)sender;
if (gesture.state == UIGestureRecognizerStateBegan)
{
// 记录捏合手势开始时的缩放系数
m_fStartScale = m_fScale;
}
// 捏合手势默认的系数是1.0
// 当识别为放大手势时,系数会从1.0开始递加; 当识别为缩小手势时,系数会从1.0开始递减,直到为0.0
CGFloat scale = gesture.scale + m_fStartScale - 1.0;
// 锁定缩放倍数,缩放倍数只能在1.0~3.0之间
if (scale - 1.0 < 0.000001)
{
scale = 1.0;
}
else if (scale - 3.0 > 0.000001)
{
scale = 3.0;
}
m_fScale = scale;
}
-(void)captureImage:(UIImage*)org scale:(CGFloat)scale startPoint:(CGPoint)startPoint {
// 如果缩放倍数为1.0的话,表示不需要进行缩放处理
if (scale - 1.0 <= 0.000001)
{
return org;
}
// 根据缩放倍数计算需要显示的图像的宽度和高度
int nW = org.size.width / scale;
int nH = org.size.height / scale;
// 根据startPoint和新的宽度高度,调整新的显示起始点。
int nX = (org.size.width - startPoint.x) >= nW ? startPoint.x : (org.size.width - nW);
int nY = (org.size.height - startPoint.y) >= nH ? startPoint.y : (org.size.height - nH);
// 提取指定rect的图像块
CGImage subImageRef = CGImageCreateWidthImageInRect(org.CGImage, CGRectMake(nX, nY, nW, nH);
UIImage *capImg = [UIImage imageWidthCGImage:subImageRef];
CGImageRelease(subImageRef);
// 针对提取出来的图像块,将它还原到可现实区域大小,以实现放大的效果
UIGraphicsBeginImageContext(org.size);
[capImg drawInRect:CGRectMake(0, 0, org.size.width, org.size.height)];
UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return retImage;
}
图像处理完毕了,剩下的就是将图像画到UIView上就行了。
-(void)drawImage:(UIImage*)img {
if (img == nil)
{
return ;
}
m_pTouchView.layer.contents = (id)[self captureImage:img scale:m_fScale startPoint:m_ptStart].CGImage;
}
你发现了什么?有问题?有参数没介绍?
对,你答对了,m_pStart这个显示起始坐标还没有设置,我们一直假设的是原始坐标(0,0);
至于这个坐标,你可以再touchesBegan,touchesMoved和touchesEnded这些函数中处理一下,就可以得到坐标了,这里就不写出具体代码了,留给细心的读者作为课后作业吧。