xcode 在 swift 中以编程方式为 iOS 设置图像的拉伸参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35607634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set stretching parameters for images programmatically in swift for iOS
提问by Milad.Nozari
回答by dfri
Specifying the cap insets of your image
指定图像的大写插图
You can set the stretch specifics by making use of the UIImage
method .resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode)
.
您可以使用UIImage
方法设置拉伸细节.resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode)
。
Declaration
func resizableImageWithCapInsets(capInsets: UIEdgeInsets, resizingMode: UIImageResizingMode) -> UIImage
Description
Creates and returns a new image object with the specified cap insets and options.
A new image object with the specified cap insets and resizing mode.
Parameters
capInsets
: The values to use for the cap insets.
resizingMode
: The mode with which the interior of the image is resized.
宣言
func resizableImageWithCapInsets(capInsets: UIEdgeInsets, resizingMode: UIImageResizingMode) -> UIImage
描述
创建并返回一个具有指定上限插入和选项的新图像对象。
具有指定的帽插入和调整大小模式的新图像对象。
参数
capInsets
:用于大写插图的值。
resizingMode
:调整图像内部大小的模式。
Example: custom stretching using the specified cap insets
示例:使用指定的帽插入自定义拉伸
As an example, let's try to---programmatically---stretch my (current) profile picture along its width, precisely at my right leg (left side from viewing point of view), and leave the rest of the image with its original proportions. This could be comparable to stretching the width of some button texture to the size of its content.
举个例子,让我们尝试---以编程方式---沿着它的宽度拉伸我的(当前)个人资料图片,精确地在我的右腿(从视角来看左侧),并将图像的其余部分保留为原始图片比例。这类似于将某些按钮纹理的宽度拉伸到其内容的大小。
First, let's load our original image foo.png
as an UIImage
object:
首先,让我们将原始图像foo.png
作为UIImage
对象加载:
let foo = UIImage(named: "foo.png") // 328 x 328
Now, using .resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode)
, we'll define another UIImage
instance, with specified cap insets (to the middle of my right leg), and set resizing mode to .Stretch
:
现在,使用.resizableImageWithCapInsets(_:UIEdgeInsets, resizingMode: UIImageResizingMode)
,我们将定义另一个UIImage
实例,具有指定的帽插入(到我的右腿中间),并将调整大小模式设置为.Stretch
:
/* middle of right leg at ~ |-> 0.48: LEG :0.52 <-| along
image width (for width normalized to 1.0) */
let fooWidth = foo?.size.width ?? 0
let leftCapInset = 0.48*fooWidth
let rightCapInset = fooWidth-leftCapInset // = 0.52*fooWidth
let bar = UIEdgeInsets(top: 0, left: leftCapInset, bottom: 0, right: rightCapInset)
let fooWithInsets = foo?.resizableImageWithCapInsets(bar, resizingMode: .Stretch) ?? UIImage()
Note that 0.48
literal above corresponds to the value you enter for X
in the interface builder, as shown in the image in your question above (or as described in detail in the link provided by matt).
请注意,0.48
上面的文字对应于您X
在界面构建器中输入的值,如上面问题中的图像所示(或在 matt 提供的链接中详细描述)。
Moving on, we finally place the image with cap insets in an UIImageView
, and let the width of this image view be larger than the width of the image
继续,我们最终将带有大写插图的图像放入 an 中UIImageView
,并让此图像视图的宽度大于图像的宽度
/* put 'fooWithInsets' in an imageView.
as per default, frame will cover 'foo.png' size */
let imageView = UIImageView(image: fooWithInsets)
/* expand frame width, 328 -> 600 */
imageView.frame = CGRect(x: 0, y: 0, width: 600, height: 328)
The resulting view stretches the original image as specified, yielding an unproportionally long leg.
结果视图按指定拉伸原始图像,产生不成比例的长腿。
Now, as long as the frame of the image has 1:1
width:height
proportions (328:328
), stretching will be uniform, as if only fitting any image to a smaller/larger frame. For any frame with width
values larger than the height
(a:1
, ratio, a>1
), the leg will begin to stretch unproportionally.
现在,只要图像的框架具有1:1
width:height
比例 ( 328:328
),拉伸就会均匀,就好像只将任何图像适合较小/较大的框架一样。对于width
值大于height
( a:1
, ratio, a>1
) 的任何帧,腿将开始不成比例地拉伸。
Extension to match the X
, width
, Y
and height
stretching properties in the Interface Builder
扩展匹配X
,width
,Y
和height
在Interface Builder的拉伸性能
Finally, to thoroughly actually answer your question (which we've really only done implicitly above), we can make use of the detailed explanation of the X
, width
, Y
and height
Interface Builder stretching properties in the link provided by matt, to construct our own UIImage
extension using (apparently) the same properties, translated to cap insets in the extension:
最后,要彻底居然回答你的问题(这我们真的只是含蓄地做以上),我们可以利用的详细说明X
,width
,Y
和height
Interface Builder的拉伸性能由Matt提供的链接,来构建我们自己的UIImage
使用扩展(显然)相同的属性,转换为扩展中的上限插图:
extension UIImage {
func resizableImageWithStretchingProperties(
X X: CGFloat, width widthProportion: CGFloat,
Y: CGFloat, height heightProportion: CGFloat) -> UIImage {
let selfWidth = self.size.width
let selfHeight = self.size.height
// insets along width
let leftCapInset = X*selfWidth*(1-widthProportion)
let rightCapInset = (1-X)*selfWidth*(1-widthProportion)
// insets along height
let topCapInset = Y*selfHeight*(1-heightProportion)
let bottomCapInset = (1-Y)*selfHeight*(1-heightProportion)
return self.resizableImageWithCapInsets(
UIEdgeInsets(top: topCapInset, left: leftCapInset,
bottom: bottomCapInset, right: rightCapInset),
resizingMode: .Stretch)
}
}
Using this extension, we can achieve the same horizontal stretching of foo.png
as above, as follows:
使用这个扩展,我们可以实现foo.png
和上面一样的水平拉伸,如下:
let foo = UIImage(named: "foo.png") // 328 x 328
let fooWithInsets = foo?.resizableImageWithStretchingProperties(
X: 0.48, width: 0, Y: 0, height: 0) ?? UIImage()
let imageView = UIImageView(image: fooWithInsets)
imageView.frame = CGRect(x: 0, y: 0, width: 600, height: 328)
Extending our example: stretching width as well as height
扩展我们的示例:拉伸宽度和高度
Now, say we want to stretch my right leg as above (along width), but in addition also my hands and left leg along the height of the image. We control this by using the Y
property in the extension above:
现在,假设我们想像上面一样拉伸我的右腿(沿宽度),但另外还要沿图像的高度拉伸我的手和左腿。我们通过使用Y
上面扩展中的属性来控制它:
let foo = UIImage(named: "foo.png") // 328 x 328
let fooWithInsets = foo?.resizableImageWithStretchingProperties(
X: 0.48, width: 0, Y: 0.45, height: 0) ?? UIImage()
let imageView = UIImageView(image: fooWithInsets)
imageView.frame = CGRect(x: 0, y: 0, width: 500, height: 500)
Yielding the following stretched image:
产生以下拉伸图像:
The extension obviously allows for a more versatile use of the cap inset stretching (comparable versatility as using the Interface Builder), but note that the extension, in its current form, does not include any user input validation, so it's up to the caller to use arguments in the correct ranges.
该扩展显然允许更广泛地使用大写插入拉伸(与使用界面生成器具有相当的多功能性),但请注意,当前形式的扩展不包括任何用户输入验证,因此由调用者决定在正确的范围内使用参数。
Finally, a relevant note for any operations covering images and their coordinates:
最后,对涉及图像及其坐标的任何操作的相关说明:
Note:Image coordinate axes
x
(width) andy
(height) run asx (width): left to right (as expected) y (height): top to bottom (don't miss this!)
注意:图像坐标轴
x
(宽度)和y
(高度)运行为x (width): left to right (as expected) y (height): top to bottom (don't miss this!)