Rectangle常用工具
通过Points和Sizes创建CGRect
CGRect RectMakeRect(CGPoint origin, CGSize size) {
return (CGRect){.origin = origin, .size = size};
}
获取一个Rectangle中心Point
CGPoint RectGetCenter(CGRect rect) {
return CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
}
围绕一个目标Point创建一个Rectangle
CGRect RectAroundCenter(CGPoint center, CGSize size){
CGFloat halfWidth = size.width / 2.0f;
CGFloat halfHeight = size.height / 2.0f;
return CGRectMake(center.x - halfWidth,center.y - halfHeight, size.width, size.height);
}
将一个rect放在另外一个rect的中心
CGRect RectCenteredInRect(CGRect rect, CGRect mainRect) {
CGFloat dx = CGRectGetMidX(mainRect) - CGRectGetMidX(rect);
CGFloat dy = CGRectGetMidY(mainRect) - CGRectGetMidY(rect);
return CGRectOffset(rect, dx, dy);
}
Fitting and Filling
Centering
居中显示,会保持原图片的默认的scale,不会放大或者缩小原图.如果图片比显示区域小,那么会在图片周边留白,如果图片比显示区域大,那么图片大小不会变,超出显示区域会直接crop.默认使用这个方法!!!
CGRect RectAroundCenter(CGPoint center, CGSize size){
CGFloat halfWidth = size.width / 2.0f;
CGFloat halfHeight = size.height / 2.0f;
return CGRectMake(center.x - halfWidth,center.y - halfHeight, size.width, size.height);
}
Fitting
当我们使用fit方式显示到目标区域,就需要保存图片所有的内容.根据原始的aspect ratio,图片缩放以后可能是letterboxed或者pillarboxed,然后横向或者纵向有留白.这部分留白内容称为matting.Calculating a Destination by Fitting to a Rectangle:
// Multiply the size components by the factor
CGSize SizeScaleByFactor(CGSize aSize, CGFloat factor) {
return CGSizeMake(aSize.width * factor, aSize.height * factor);
}
// Calculate scale for fitting a size to a destination
CGFloat AspectScaleFit(CGSize sourceSize, CGRect destRect) {
CGSize destSize = destRect.size;
CGFloat scaleW = destSize.width / sourceSize.width;
CGFloat scaleH = destSize.height / sourceSize.height;
return MIN(scaleW, scaleH);
}
// Return a rect fitting a source to a destination
CGRect RectByFittingInRect(CGRect sourceRect, CGRect destinationRect) {
CGFloat aspect = AspectScaleFit(sourceRect.size, destinationRect);
CGSize targetSize = SizeScaleByFactor(sourceRect.size, aspect);
return RectAroundCenter( RectGetCenter(destinationRect), targetSize);
}
Filling
前面讲到Fitting会在两边有留白.那么如果需要将图片全部填满目标区域,同时保持aspect ratio不变,那么使用filling方式 -- 一般是将soruce rectangle拉升到刚刚好覆盖dest rectangle,然后crop掉超出dest rectangle的部分.总之肯定会crop一部分(有可能是左右部分.或者上下部分)
// Calculate scale for filling a destination
CGFloat AspectScaleFill(CGSize sourceSize, CGRect destRect) {
CGSize destSize = destRect.size;
CGFloat scaleW = destSize.width / sourceSize.width;
CGFloat scaleH = destSize.height / sourceSize.height;
return MAX(scaleW, scaleH);
}
// Return a rect that fills the destination
CGRect RectByFillingRect(CGRect sourceRect, CGRect destinationRect) {
CGFloat aspect = AspectScaleFill(sourceRect.size, destinationRect);
CGSize targetSize = SizeScaleByFactor(sourceRect.size, aspect);
return RectAroundCenter(RectGetCenter(destinationRect), targetSize);
}
Squeezing
最后一种常用的显示图片到目标区域的方法是拉伸..不过很少用这种方法