Iphone 调整图像大小并以图像为中心进行裁剪
因此,目前我正在尝试裁剪和调整图片大小,以适应特定的大小,而不会丢失比例 一个小图片来展示我的意思: 我玩了一点,但他们不与png的工作和有问题的GIF。而且图像不会被裁剪 是否有人建议如何以最佳方式调整大小,或者可能有指向现有库/分类/任何内容的链接 谢谢你的提示Iphone 调整图像大小并以图像为中心进行裁剪,iphone,objective-c,cocoa-touch,ios,Iphone,Objective C,Cocoa Touch,Ios,因此,目前我正在尝试裁剪和调整图片大小,以适应特定的大小,而不会丢失比例 一个小图片来展示我的意思: 我玩了一点,但他们不与png的工作和有问题的GIF。而且图像不会被裁剪 是否有人建议如何以最佳方式调整大小,或者可能有指向现有库/分类/任何内容的链接 谢谢你的提示 p、 美国:ios是否实现了一个“选择摘录”功能,这样我就有了正确的比例,并且只需要缩放它 此方法将执行您想要的操作,并且是UIImage的一个类别,便于使用。我使用了resize-then-crop,如果你想裁剪然后调整大小,你
p、 美国:ios是否实现了一个“选择摘录”功能,这样我就有了正确的比例,并且只需要缩放它 此方法将执行您想要的操作,并且是UIImage的一个类别,便于使用。我使用了resize-then-crop,如果你想裁剪然后调整大小,你可以很容易地切换代码。函数中的边界检查纯粹是说明性的。您可能希望执行一些不同的操作,例如相对于outputImage维度居中裁剪矩形,但这应该可以使您足够靠近,以便进行所需的任何其他更改
@implementation UIImage( resizeAndCropExample )
- (UIImage *) resizeToSize:(CGSize) newSize thenCropWithRect:(CGRect) cropRect {
CGContextRef context;
CGImageRef imageRef;
CGSize inputSize;
UIImage *outputImage = nil;
CGFloat scaleFactor, width;
// resize, maintaining aspect ratio:
inputSize = self.size;
scaleFactor = newSize.height / inputSize.height;
width = roundf( inputSize.width * scaleFactor );
if ( width > newSize.width ) {
scaleFactor = newSize.width / inputSize.width;
newSize.height = roundf( inputSize.height * scaleFactor );
} else {
newSize.width = width;
}
UIGraphicsBeginImageContext( newSize );
context = UIGraphicsGetCurrentContext();
// added 2016.07.29, flip image vertically before drawing:
CGContextSaveGState(context);
CGContextTranslateCTM(context, 0, newSize.height);
CGContextScaleCTM(context, 1, -1);
CGContextDrawImage(context, CGRectMake(0, 0, newSize.width, newSize.height, self.CGImage);
// // alternate way to draw
// [self drawInRect: CGRectMake( 0, 0, newSize.width, newSize.height )];
CGContextRestoreGState(context);
outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
inputSize = newSize;
// constrain crop rect to legitimate bounds
if ( cropRect.origin.x >= inputSize.width || cropRect.origin.y >= inputSize.height ) return outputImage;
if ( cropRect.origin.x + cropRect.size.width >= inputSize.width ) cropRect.size.width = inputSize.width - cropRect.origin.x;
if ( cropRect.origin.y + cropRect.size.height >= inputSize.height ) cropRect.size.height = inputSize.height - cropRect.origin.y;
// crop
if ( ( imageRef = CGImageCreateWithImageInRect( outputImage.CGImage, cropRect ) ) ) {
outputImage = [[[UIImage alloc] initWithCGImage: imageRef] autorelease];
CGImageRelease( imageRef );
}
return outputImage;
}
@end
我在一个应用程序中遇到了相同的问题,并开发了以下代码:
+ (UIImage*)resizeImage:(UIImage*)image toFitInSize:(CGSize)toSize
{
UIImage *result = image;
CGSize sourceSize = image.size;
CGSize targetSize = toSize;
BOOL needsRedraw = NO;
// Check if width of source image is greater than width of target image
// Calculate the percentage of change in width required and update it in toSize accordingly.
if (sourceSize.width > toSize.width) {
CGFloat ratioChange = (sourceSize.width - toSize.width) * 100 / sourceSize.width;
toSize.height = sourceSize.height - (sourceSize.height * ratioChange / 100);
needsRedraw = YES;
}
// Now we need to make sure that if we chnage the height of image in same proportion
// Calculate the percentage of change in width required and update it in target size variable.
// Also we need to again change the height of the target image in the same proportion which we
/// have calculated for the change.
if (toSize.height < targetSize.height) {
CGFloat ratioChange = (targetSize.height - toSize.height) * 100 / targetSize.height;
toSize.height = targetSize.height;
toSize.width = toSize.width + (toSize.width * ratioChange / 100);
needsRedraw = YES;
}
// To redraw the image
if (needsRedraw) {
UIGraphicsBeginImageContext(toSize);
[image drawInRect:CGRectMake(0.0, 0.0, toSize.width, toSize.height)];
result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
}
// Return the result
return result;
}
+(UIImage*)调整图像大小:(UIImage*)图像大小:(CGSize)调整大小
{
UIImage*结果=图像;
CGSize sourceSize=image.size;
CGSize targetSize=toSize;
BOOL needsRedraw=否;
//检查源图像的宽度是否大于目标图像的宽度
//计算所需宽度变化的百分比,并相应地在toSize中更新它。
if(sourceSize.width>toSize.width){
CGFloat ratioChange=(sourceSize.width-toSize.width)*100/sourceSize.width;
toSize.height=sourceSize.height-(sourceSize.height*比率变化/100);
需要绘制=是;
}
//现在我们需要确定,如果我们以相同的比例改变图像的高度
//计算所需宽度变化的百分比,并在目标尺寸变量中更新它。
//此外,我们还需要再次改变目标图像的高度,改变的比例与我们看到的相同
///我们已经计算了变化。
如果(toSize.height
您可以根据需要修改它。在库中预览图像时也有相同的任务。对于固定裁剪区域(用于SwiftUI的图像和用于Kotiln的Canvas Rect),我希望裁剪图像的中心内容-最多裁剪图像一侧的内容。(见下文解释) 这里是解决方案 Swift
func getImageCropped(srcImage : UIImage, sizeToCrop : CGSize) -> UIImage{
let ratioImage = Double(srcImage.cgImage!.width ) / Double(srcImage.cgImage!.height )
let ratioCrop = Double(sizeToCrop.width) / Double(sizeToCrop.height)
let cropRect: CGRect = {
if(ratioCrop > 1.0){
// crop LAND -> fit image HORIZONTALLY
let widthRatio = CGFloat(srcImage.cgImage!.width) / CGFloat(sizeToCrop.width)
var cropWidth = Int(sizeToCrop.width * widthRatio)
var cropHeight = Int(sizeToCrop.height * widthRatio)
var cropX = 0
var cropY = srcImage.cgImage!.height / 2 - cropHeight / 2
// [L1] [L2] : OK
if(ratioImage > 1.0) {
// image LAND
// [L3] : OK
if(cropHeight > srcImage.cgImage!.height) {
// [L4] : Crop-Area exceeds Image-Area > change crop orientation to PORTrait
let heightRatio = CGFloat(srcImage.cgImage!.height) / CGFloat(sizeToCrop.height)
cropWidth = Int(sizeToCrop.width * heightRatio)
cropHeight = Int(sizeToCrop.height * heightRatio)
cropX = srcImage.cgImage!.width / 2 - cropWidth / 2
cropY = 0
}
}
return CGRect(x: cropX, y: cropY, width: cropWidth, height: cropHeight)
}
else if(ratioCrop < 1.0){
// crop PORT -> fit image VERTICALLY
let heightRatio = CGFloat(srcImage.cgImage!.height) / CGFloat(sizeToCrop.height)
var cropWidth = Int(sizeToCrop.width * heightRatio)
var cropHeight = Int(sizeToCrop.height * heightRatio)
var cropX = srcImage.cgImage!.width / 2 - cropWidth / 2
var cropY = 0
// [P1] [P2] : OK
if(ratioImage < 1.0) {
// // image PORT
// [P3] : OK
if(cropWidth > srcImage.cgImage!.width) {
// [L4] : Crop-Area exceeds Image-Area > change crop orientation to LANDscape
let widthRatio = CGFloat(srcImage.cgImage!.width) / CGFloat(sizeToCrop.width)
cropWidth = Int(sizeToCrop.width * widthRatio)
cropHeight = Int(sizeToCrop.height * widthRatio)
cropX = 0
cropY = srcImage.cgImage!.height / 2 - cropHeight / 2
}
}
return CGRect(x: cropX, y: cropY, width: cropWidth, height: cropHeight)
}
else {
// CROP CENTER SQUARE
var fitSide = 0
var cropX = 0
var cropY = 0
if (ratioImage > 1.0){
// crop LAND -> fit image HORIZONTALLY !!!!!!
fitSide = srcImage.cgImage!.height
cropX = srcImage.cgImage!.width / 2 - fitSide / 2
}
else if (ratioImage < 1.0){
// crop PORT -> fit image VERTICALLY
fitSide = srcImage.cgImage!.width
cropY = srcImage.cgImage!.height / 2 - fitSide / 2
}
else{
// ImageAre and GropArea are square both
fitSide = srcImage.cgImage!.width
}
return CGRect(x: cropX, y: cropY, width: fitSide, height: fitSide)
}
}()
let imageRef = srcImage.cgImage!.cropping(to: cropRect)
let cropped : UIImage = UIImage(cgImage: imageRef!, scale: 0, orientation: srcImage.imageOrientation)
return cropped
}
Kotlin解决方案的工作原理相同。相信我)+1选择,我现在需要你的帮助。如果你得到答案意味着请张贴答案,因为我需要同样的东西请+1详细演示您的视图翻转了吗?此代码适用于标准视图。如果它被翻转,你可能不得不改变当前的转换矩阵。选民:问题是什么?这在2010年效果很好。图片上下颠倒,哈哈。这个愚蠢的简单任务很难正确完成,这说明了一些关于图书馆的事情。。。2015年非常令人沮丧,因为有这么多伟大的技术,我们仍然在用这些废话来推敲。我已经将代码改为使用
drawInRect:
,这可能比五年前的答案更好。请试一试,让我知道是否有效。
data class RectCrop(val x: Int, val y: Int, val width: Int, val height: Int)
fun getImageCroppedShort(srcBitmap: Bitmap, sizeToCrop: Size):Bitmap {
val ratioImage = srcBitmap.width.toFloat() / srcBitmap.height.toFloat()
val ratioCrop = sizeToCrop.width.toFloat() / sizeToCrop.height.toFloat()
// 1. choose fit size
val cropRect: RectCrop =
if(ratioCrop > 1.0){
// crop LAND
val widthRatio = srcBitmap.width.toFloat() / sizeToCrop.width.toFloat()
var cropWidth = (sizeToCrop.width * widthRatio).toInt()
var cropHeight= (sizeToCrop.height * widthRatio).toInt()
var cropX = 0
var cropY = srcBitmap.height / 2 - cropHeight / 2
if(ratioImage > 1.0) {
// image LAND
if(cropHeight > srcBitmap.height) {
val heightRatio = srcBitmap.height.toFloat() / sizeToCrop.height.toFloat()
cropWidth = (sizeToCrop.width * heightRatio).toInt()
cropHeight = (sizeToCrop.height * heightRatio).toInt()
cropX = srcBitmap.width / 2 - cropWidth / 2
cropY = 0
}
}
RectCrop(cropX, cropY, cropWidth, cropHeight)
}
else if(ratioCrop < 1.0){
// crop PORT
val heightRatio = srcBitmap.height.toFloat() / sizeToCrop.height.toFloat()
var cropWidth = (sizeToCrop.width * heightRatio).toInt()
var cropHeight= (sizeToCrop.height * heightRatio).toInt()
var cropX = srcBitmap.width / 2 - cropWidth / 2
var cropY = 0
if(ratioImage < 1.0) {
// image PORT
if(cropWidth > srcBitmap.width) {
val widthRatio = srcBitmap.width.toFloat() / sizeToCrop.width.toFloat()
cropWidth = (sizeToCrop.width * widthRatio).toInt()
cropHeight = (sizeToCrop.height * widthRatio).toInt()
cropX = 0
cropY = srcBitmap.height / 2 - cropHeight / 2
}
}
RectCrop(cropX, cropY, cropWidth, cropHeight)
}
else {
// CROP CENTER SQUARE
var fitSide = 0
var cropX = 0
var cropY = 0
if (ratioImage > 1.0){
fitSide = srcBitmap.height
cropX = srcBitmap.width/ 2 - fitSide / 2
}
else if (ratioImage < 1.0){
fitSide = srcBitmap.width
cropY = srcBitmap.height / 2 - fitSide / 2
}
else{
fitSide = srcBitmap.width
}
RectCrop(cropX, cropY, fitSide, fitSide)
}
return Bitmap.createBitmap(
srcBitmap,
cropRect.x,
cropRect.y,
cropRect.width,
cropRect.height)
}
var body: some View {
// IMAGE LAND
let ORIG_NAME = "image_land.jpg"
let ORIG_W = 400.0
let ORIG_H = 265.0
// > crop Land
let cropW = 400.0
let cropH = 200.0
// > crop Port
// let cropW = 50.0
// let cropH = 265.0
// > crop Center Square
// let cropW = 265.0
// let cropH = 265.0
// IMAGE PORT
// let ORIG_NAME = "image_port.jpg"
// let ORIG_W = 350.0
// let ORIG_H = 500.0
// > crop Land
// let cropW = 350.0
// let cropH = 410.0
// > crop Port
// let cropW = 190.0
// let cropH = 500.0
// > crop Center Square
// let cropW = 350.0
// let cropH = 350.0
let imageOriginal = UIImage(named: ORIG_NAME)!
let imageCropped = self.getImageCroppedShort(srcImage: imageOriginal, sizeToCrop: CGSize(width: cropW, height: cropH))
return VStack{
HStack{
Text("ImageArea \nW:\(Int(ORIG_W)) \nH:\(Int(ORIG_H))").font(.body)
Text("CropArea \nW:\(Int(cropW)) \nH:\(Int(cropH))").font(.body)
}
ZStack{
Image(uiImage: imageOriginal)
.resizable()
.opacity(0.4)
Image(uiImage: imageCropped)
.resizable()
.frame(width: CGFloat(cropW), height: CGFloat(cropH))
}
.frame(width: CGFloat(ORIG_W), height: CGFloat(ORIG_H))
.background(Color.black)
}
}