Iphone 调整图像大小并以图像为中心进行裁剪

Iphone 调整图像大小并以图像为中心进行裁剪,iphone,objective-c,cocoa-touch,ios,Iphone,Objective C,Cocoa Touch,Ios,因此,目前我正在尝试裁剪和调整图片大小,以适应特定的大小,而不会丢失比例 一个小图片来展示我的意思: 我玩了一点,但他们不与png的工作和有问题的GIF。而且图像不会被裁剪 是否有人建议如何以最佳方式调整大小,或者可能有指向现有库/分类/任何内容的链接 谢谢你的提示 p、 美国:ios是否实现了一个“选择摘录”功能,这样我就有了正确的比例,并且只需要缩放它 此方法将执行您想要的操作,并且是UIImage的一个类别,便于使用。我使用了resize-then-crop,如果你想裁剪然后调整大小,你

因此,目前我正在尝试裁剪和调整图片大小,以适应特定的大小,而不会丢失比例

一个小图片来展示我的意思:

我玩了一点,但他们不与png的工作和有问题的GIF。而且图像不会被裁剪

是否有人建议如何以最佳方式调整大小,或者可能有指向现有库/分类/任何内容的链接

谢谢你的提示


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)
            }
        }