jpm*_*jpm 111 cocoa-touch resize image objective-c ios
我的应用程序是从网络下载一组图像文件,并将它们保存到本地iPhone磁盘.其中一些图像的尺寸非常大(例如,宽度大于500像素).由于iPhone甚至没有足够大的显示器来显示原始尺寸的图像,我计划将图像尺寸调整为更小的尺寸以节省空间/性能.
此外,其中一些图像是JPEG,并且它们不会保存为通常的60%质量设置.
如何使用iPhone SDK调整图片大小,如何更改JPEG图像的质量设置?
Bra*_*son 243
提供了几个建议作为这个问题的答案.我已经建议使用相关代码在本文中描述的技术:
+ (UIImage*)imageWithImage:(UIImage*)image
scaledToSize:(CGSize)newSize;
{
UIGraphicsBeginImageContext( newSize );
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
Run Code Online (Sandbox Code Playgroud)
就图像的存储而言,与iPhone一起使用的最快图像格式是PNG,因为它对该格式进行了优化.但是,如果要将这些图像存储为JPEG,则可以使用UIImage并执行以下操作:
NSData *dataForJPEGFile = UIImageJPEGRepresentation(theImage, 0.6);
Run Code Online (Sandbox Code Playgroud)
这将创建一个NSData实例,其中包含60%质量设置的JPEG图像的原始字节.然后可以将该NSData实例的内容写入磁盘或缓存在内存中.
los*_*sit 65
调整图像大小的最简单,最直接的方法就是这样
float actualHeight = image.size.height;
float actualWidth = image.size.width;
float imgRatio = actualWidth/actualHeight;
float maxRatio = 320.0/480.0;
if(imgRatio!=maxRatio){
if(imgRatio < maxRatio){
imgRatio = 480.0 / actualHeight;
actualWidth = imgRatio * actualWidth;
actualHeight = 480.0;
}
else{
imgRatio = 320.0 / actualWidth;
actualHeight = imgRatio * actualHeight;
actualWidth = 320.0;
}
}
CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight);
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Run Code Online (Sandbox Code Playgroud)
Pul*_*yal 25
上述方法适用于小图像,但是当您尝试调整非常大的图像大小时,您将很快耗尽内存并使应用程序崩溃.更好的方法是使用CGImageSourceCreateThumbnailAtIndex调整图像大小而不首先完全解码它.
如果您有要调整大小的图像的路径,则可以使用以下命令:
- (void)resizeImageAtPath:(NSString *)imagePath {
// Create the image source (from path)
CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);
// To create image source from UIImage, use this
// NSData* pngData = UIImagePNGRepresentation(image);
// CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)pngData, NULL);
// Create thumbnail options
CFDictionaryRef options = (__bridge CFDictionaryRef) @{
(id) kCGImageSourceCreateThumbnailWithTransform : @YES,
(id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
(id) kCGImageSourceThumbnailMaxPixelSize : @(640)
};
// Generate the thumbnail
CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
CFRelease(src);
// Write the thumbnail at path
CGImageWriteToFile(thumbnail, imagePath);
}
Run Code Online (Sandbox Code Playgroud)
更多细节在这里.
cod*_*urn 18
在不丢失纵横比的情况下缩放图像的最佳方法(即不拉伸行李)是使用此方法:
//to scale images without changing aspect ratio
+ (UIImage *)scaleImage:(UIImage *)image toSize:(CGSize)newSize {
float width = newSize.width;
float height = newSize.height;
UIGraphicsBeginImageContext(newSize);
CGRect rect = CGRectMake(0, 0, width, height);
float widthRatio = image.size.width / width;
float heightRatio = image.size.height / height;
float divisor = widthRatio > heightRatio ? widthRatio : heightRatio;
width = image.size.width / divisor;
height = image.size.height / divisor;
rect.size.width = width;
rect.size.height = height;
//indent in case of width or height difference
float offset = (width - height) / 2;
if (offset > 0) {
rect.origin.y = offset;
}
else {
rect.origin.x = -offset;
}
[image drawInRect: rect];
UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return smallImage;
}
Run Code Online (Sandbox Code Playgroud)
将此方法添加到Utility类中,以便您可以在整个项目中使用它,并像这样访问它:
xyzImageView.image = [Utility scaleImage:yourUIImage toSize:xyzImageView.frame.size];
Run Code Online (Sandbox Code Playgroud)
该方法在保持纵横比的同时负责缩放.如果按比例缩小的图像宽度大于高度(或反之亦然),它还会向图像添加缩进.
如果您可以控制服务器,我强烈建议您使用ImageMagik调整图像服务器端的大小.下载大图像并在手机上调整大小是浪费了许多宝贵的资源 - 带宽,电池和内存.所有这些都在手机上很少见.
我为Swift中的图像缩放开发了一个终极解决方案.
您可以使用它来调整图像大小以填充,宽高比填充或宽高比适合指定的大小.
您可以将图像对齐到中心或四个边和四个角中的任何一个.
如果原始图像和目标尺寸的纵横比不相等,您还可以修剪额外的空间.
enum UIImageAlignment {
case Center, Left, Top, Right, Bottom, TopLeft, BottomRight, BottomLeft, TopRight
}
enum UIImageScaleMode {
case Fill,
AspectFill,
AspectFit(UIImageAlignment)
}
extension UIImage {
func scaleImage(width width: CGFloat? = nil, height: CGFloat? = nil, scaleMode: UIImageScaleMode = .AspectFit(.Center), trim: Bool = false) -> UIImage {
let preWidthScale = width.map { $0 / size.width }
let preHeightScale = height.map { $0 / size.height }
var widthScale = preWidthScale ?? preHeightScale ?? 1
var heightScale = preHeightScale ?? widthScale
switch scaleMode {
case .AspectFit(_):
let scale = min(widthScale, heightScale)
widthScale = scale
heightScale = scale
case .AspectFill:
let scale = max(widthScale, heightScale)
widthScale = scale
heightScale = scale
default:
break
}
let newWidth = size.width * widthScale
let newHeight = size.height * heightScale
let canvasWidth = trim ? newWidth : (width ?? newWidth)
let canvasHeight = trim ? newHeight : (height ?? newHeight)
UIGraphicsBeginImageContextWithOptions(CGSizeMake(canvasWidth, canvasHeight), false, 0)
var originX: CGFloat = 0
var originY: CGFloat = 0
switch scaleMode {
case .AspectFit(let alignment):
switch alignment {
case .Center:
originX = (canvasWidth - newWidth) / 2
originY = (canvasHeight - newHeight) / 2
case .Top:
originX = (canvasWidth - newWidth) / 2
case .Left:
originY = (canvasHeight - newHeight) / 2
case .Bottom:
originX = (canvasWidth - newWidth) / 2
originY = canvasHeight - newHeight
case .Right:
originX = canvasWidth - newWidth
originY = (canvasHeight - newHeight) / 2
case .TopLeft:
break
case .TopRight:
originX = canvasWidth - newWidth
case .BottomLeft:
originY = canvasHeight - newHeight
case .BottomRight:
originX = canvasWidth - newWidth
originY = canvasHeight - newHeight
}
default:
break
}
self.drawInRect(CGRectMake(originX, originY, newWidth, newHeight))
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Run Code Online (Sandbox Code Playgroud)
以下是应用此解决方案的示例.
灰色矩形是目标站点图像将调整大小.浅蓝色矩形中的蓝色圆圈是图像(我使用圆圈,因为它很容易看到它在不保留方面的情况下缩放).如果通过,浅橙色标记将被修剪的区域trim: true.
缩放之前和之后的宽高比适合:
方面拟合的另一个例子:
Aspect适合顶部对齐:
方面填充:
填充:
我在我的示例中使用了upscaling,因为它更易于演示,但解决方案也适用于降尺度.
对于JPEG压缩,您应该使用:
let compressionQuality: CGFloat = 0.75 // adjust to change JPEG quality
if let data = UIImageJPEGRepresentation(image, compressionQuality) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
你可以通过Xcode游乐场查看我的要点.
| 归档时间: |
|
| 查看次数: |
171894 次 |
| 最近记录: |