0

我希望把这个写出来可能对我的问题有所帮助。我有包含面部的图像,我想重新裁剪这些图像,尊重纵横比,同时尽可能多地保留面部。

我想将图像裁剪为任意矩形,可以是高、短、正方形或任何高达 4:1 的宽高比。我想尽可能避免裁剪出我指定的面部或特征(作为图像矩形的内部矩形)。EG 我有一个 (0,0,500, 300) 的图像矩形和一个 (20, 40, 75, 75) 的特征矩形,我想将它裁剪(考虑其纵横比)为 (0,0, 320,200),同时最小限度地裁剪面部矩形。

我有一个中心裁剪的工作实现,我确定图像的较大一侧并根据相同的比例缩放另一侧,将 x 和 y 设置为缩放 w/h 的中心 - 目标 w/h。

为了清楚起见,签名看起来像这样(在 Obj-C 中):

(CGRect)crop:(CGSize)sourceSize toFitSize:(CGSize)fitSize withoutCroppingRect:(CGRect)featuresRect

sourceSize原始图像的大小在哪里,fitSize是我想要将图像裁剪成的形状,并且featuresRect是一个矩形,在(0,0,sourceSize.width, sourceSize,height).

也许这应该作为以特征矩形为中心的“中心裁剪”来完成?试图理解这甚至意味着什么。

4

1 回答 1

0

试试看,我认为它可以满足您的需求,或者至少可以将您推向正确的方向。输出矩形保持与源图像矩形相同的纵横比。

示例用法:

 CGRect sizedRect = [self cropSize:self.inputView.image.size
                         toFitSize:self.outputView.bounds.size
               withoutCroppingRect:self.regionOfInterest.frame];

 CGImageRef cgImage = self.inputView.image.CGImage;

 CGImageRef cgCroppedImage =  CGImageCreateWithImageInRect (
                                         cgImage,
                                         sizedRect
                                         );

 self.outputView.image = [UIImage imageWithCGImage:cgCroppedImage];

您需要考虑许多问题,特别是:
- 您返回的矩形可能大于 fitSize,因为它不会裁剪 featuresRect,因此您可能需要检查这一点并在之后缩放图像应用裁剪(或适当地设置输出 imageView 的 scaleToFit)。
- 您从哪里获得 ROI 帧数据?它是相对于原始源图像,还是相对于包含源图像的 imageView。如果是后者,您需要确保源图像的大小与它的 imageView 为 1:1,因为裁剪矩形应用于图像,而不是 imageView。
- 输出 imageView 小于输入 imageView。我不确定如果它更大会做什么,但它可能会引入类似的缩放问题。
- 您将需要添加除零错误检查。

-     (CGRect)cropSize:(CGSize)sourceSize 
             toFitSize:(CGSize)fitSize
   withoutCroppingRect:(CGRect)featuresRect
{
    CGRect result = CGRectZero;
    BOOL fitSizeIsTaller;
    CGFloat sourceRatio = sourceSize.width / sourceSize.height;
    CGFloat fitRatio    = fitSize.width    / fitSize.height;
     if (sourceRatio > fitRatio)
            fitSizeIsTaller = YES;
     else   fitSizeIsTaller = NO;

        //size sourceRect to fitSize
    if (fitSizeIsTaller){
        result.size.width  = fitSize.width;
        result.size.height = result.size.width / sourceRatio;
    } else {
        result.size.height = fitSize.height;
        result.size.width  = result.size.height * sourceRatio;
    }
        //make sure it is at least as large as fitSize
    if (result.size.height < featuresRect.size.height) {
        result.size.height = featuresRect.size.height;
        result.size.width  = result.size.height * sourceRatio;
    }

    if (result.size.width  < featuresRect.size.width) {
        result.size.width  = featuresRect.size.width;
        result.size.height = result.size.width / sourceRatio;
    }

            //locate resultRect in center
    result.origin.x = (sourceSize.width  - result.size.width )/2;
    result.origin.y = (sourceSize.height - result.size.height)/2;

            //shift origin of result to make sure it includes ROI

    if (featuresRect.origin.x < result.origin.x )    //shift right?
              result.origin.x = featuresRect.origin.x;
    else
        if ((featuresRect.origin.x + featuresRect.size.width)  
               >  (result.origin.x + result.size.width))  //shift left?
            result.origin.x = (featuresRect.origin.x + featuresRect.size.width)
                            - result.size.width;

    if (featuresRect.origin.y < result.origin.y )    //shift up?
              result.origin.y = featuresRect.origin.y;
    else
        if ((featuresRect.origin.y + featuresRect.size.height)  
                > (result.origin.y + result.size.height))  //shift down?
            result.origin.y = (featuresRect.origin.y+featuresRect.size.height)
                            - result.size.height;
    return result;
}
于 2013-01-14T17:11:07.170 回答