Ios 对图像进行方形裁剪,导致图像拉伸
尝试对UIImage执行中心裁剪时,我得到以下结果(左侧是Ios 对图像进行方形裁剪,导致图像拉伸,ios,objective-c,uiimage,Ios,Objective C,Uiimage,尝试对UIImage执行中心裁剪时,我得到以下结果(左侧是640*1136处的原始图像,右侧是在320*320处安装到方形UIImageView上的裁剪图像): 转向: 我对ratio元素做了很多修改,以便它能够正确地检测到要修剪的量:使用图像的较短一侧,根据short\u side/width\u of u required\u rect构建一个比率,但在这种情况下它似乎不起作用。谢谢你的帮助 - (UIImage *)squareImageWithImage:(UIImage *)imag
640*1136
处的原始图像,右侧是在320*320
处安装到方形UIImageView
上的裁剪图像):
转向:
我对ratio元素做了很多修改,以便它能够正确地检测到要修剪的量:使用图像的较短一侧,根据short\u side/width\u of u required\u rect
构建一个比率,但在这种情况下它似乎不起作用。谢谢你的帮助
- (UIImage *)squareImageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
double ratio;
double delta;
CGPoint offset;
//make a new square size, that is the resized imaged width
CGSize sz = CGSizeMake(newSize.width, newSize.width);
//figure out if the picture is landscape or portrait, then
//calculate scale factor and offset
if (image.size.width > image.size.height) {
ratio = newSize.width / image.size.width;
delta = (ratio*image.size.width - ratio*image.size.height);
offset = CGPointMake(delta/2, 0);
} else {
ratio = newSize.width / image.size.height;
delta = (ratio*image.size.height - ratio*image.size.width);
offset = CGPointMake(0, delta/2);
}
//make the final clipping rect based on the calculated values
CGRect clipRect = CGRectMake(-offset.x, -offset.y,
(ratio * image.size.width) + delta,
(ratio * image.size.height) + delta);
//for retina consideration
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(sz, YES, 0.0);
} else {
UIGraphicsBeginImageContext(sz);
}
UIRectClip(clipRect);
[image drawInRect:clipRect];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
使用此代码调整图像大小
// Returns image resized to the desired CGSize
- (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContext(newSize);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
编辑:你基本上也在这里重画。如果反复使用同一个图像,最好调用一次并将结果保存为文件。在以后的调用中加载它而不是原始的
编辑2:好的,那么你要做的是保持纵横比,同时将图像拟合成正方形。上面的代码基本上通过调整图像的大小将其放入一个正方形中,但它不保持纵横比。保持纵横比的另一种方法是找到缩小图像两个维度中较大维度的因子,然后用相同的因子缩小另一个维度。如果你有问题,请告诉我 试试这个:
- (UIImage *)squareImageFromImage:(UIImage *)image scaledToSize:(CGFloat)newSize {
CGAffineTransform scaleTransform;
CGPoint origin;
if (image.size.width > image.size.height) {
CGFloat scaleRatio = newSize / image.size.height;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake(-(image.size.width - image.size.height) / 2.0f, 0);
} else {
CGFloat scaleRatio = newSize / image.size.width;
scaleTransform = CGAffineTransformMakeScale(scaleRatio, scaleRatio);
origin = CGPointMake(0, -(image.size.height - image.size.width) / 2.0f);
}
CGSize size = CGSizeMake(newSize, newSize);
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
} else {
UIGraphicsBeginImageContext(size);
}
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextConcatCTM(context, scaleTransform);
[image drawAtPoint:origin];
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
fumoboy007代码的Swift3版本
func squareImage(img: UIImage, scaledToSize newSize: CGFloat) -> UIImage {
var scaleTransform: CGAffineTransform
var origin: CGPoint
var image = img
if image.size.width > image.size.height {
let scaleRatio: CGFloat = newSize / image.size.height
scaleTransform = CGAffineTransform(scaleX: scaleRatio, y: scaleRatio)
origin = CGPoint(x: -(image.size.width - image.size.height) / 2.0, y: 0)
}
else {
let scaleRatio: CGFloat = newSize / image.size.width
scaleTransform = CGAffineTransform(scaleX: scaleRatio, y: scaleRatio)
origin = CGPoint(x: 0, y: -(image.size.height - image.size.width) / 2.0)
}
let size = CGSize(width: newSize, height: newSize)
if image.size.width > image.size.height {
UIGraphicsBeginImageContextWithOptions(size, true, 0)
}
else {
UIGraphicsBeginImageContext(size)
}
let context: CGContext? = UIGraphicsGetCurrentContext()
context?.concatenate(scaleTransform)
image.draw(at: origin)
image = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return image
}
仅供参考-iOS 4.0中添加了
UIScreen
的scale
属性。没有必要再检查它了。你没有被修剪。您正在将整个图像重绘到一个较小的区域。在“ios裁剪图像”上进行搜索,您将找到许多解决问题的方法。谢谢@rmaddy-我想我正在裁剪和重画图像(压扁的图像有8个垂直平方计数,而原始图像有11个以上)。您不想进入clipRect
。您希望以原始纵横比绘制图像,以便在clipRect
中仅渲染要保留的部分。感谢用户2891327。虽然这在使用后向摄像头时效果很好,但在使用前向摄像头时,图像仍然会被压扁。奇怪的是,另一组代码似乎也是如此。我添加了一些截图,以防有所帮助。这是相机拍摄的(注意,它的高宽比是9:16),没有调整到正方形:,这是在调整到正方形之后:感谢您回答@fumoboy007-不幸的是,它没有工作:/图像放大了,没有正确裁剪。我还删除了boolislandscape
,因为它没有在代码的其余部分中使用。嗯……这很奇怪。我能看一些截图吗?啊,忘了缩放…等等。前后摄像头都很好用。非常感谢。我只是添加了一点更改,因为newSize
是CGSize
而不是CGFloat
。不客气。=)对于字母装箱,是的,几乎翻转缩放和裁剪逻辑,并绘制一个黑色矩形(或任何颜色)。