我希望写出来可能有助于解决我的问题。我有包含面孔的图像,我想重新调整这些图像,尊重纵横比,同时保持尽可能多的面部。
我想将图像裁剪为任意矩形,可以是高,短,正方形或任何高达4:1的宽高比。尽可能地,我想避免裁剪出我指定的面部或特征(作为图像矩形的内部矩形)。例如。我有一个(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)
的范围内
也许这应该作为“中心裁剪”完成,以特征矩形为中心?试图绕过这甚至意味着什么。
答案 0 :(得分:0)
顺便说一句,我认为它可以满足您的需求,或者至少可以帮助您朝着正确的方向前进。输出rect保持与源图像rect相同的宽高比。
使用示例:
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];
您需要考虑许多问题,尤其是:
- 您返回的rect可能比fitSize大,因为它不会裁剪featuresRect,因此您可能必须检查这个并在应用裁剪后缩放图像(或者适当地设置输出imageView的scaleToFit)。
- 您从哪里获得ROI框架数据?它是相对于原始源图像还是包含源图像的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;
}