【问题标题】:How to transform and enlarge imageview into a shape (swift3)如何将imageview转换和放大为形状(swift3)
【发布时间】:2017-03-24 18:26:03
【问题描述】:

我想要做的是取一个正方形的图像视图,并使其成为一个 5 点的图像视图,顶部和底部的 3 点三角形形状到底部的点。

public func shapeImage(with bezierPath: UIBezierPath, size: CGSize, fillColor: UIColor? = UIColor.clear,
                         strokeColor: UIColor? = nil, strokeWidth: CGFloat = 0.0) -> UIImage! {

UIGraphicsBeginImageContext(size)
let context = UIGraphicsGetCurrentContext()
var image = UIImage(data: try! Data(contentsOf: URL(string:"https://a248.e.akamai.net/secure.meetupstatic.com/photos/member/5/3/5/e/highres_260901342.jpeg")!))!

if let context = context {
    context.saveGState()
    context.addPath(bezierPath.cgPath)

    if let strokeColor = strokeColor {
        strokeColor.setStroke()
        context.setLineWidth(strokeWidth)
    } else {
        UIColor.clear.setStroke()
    }

    fillColor?.setFill()
    context.drawPath(using: .fillStroke)

    image = UIGraphicsGetImageFromCurrentImageContext()!
    context.restoreGState()
    UIGraphicsEndImageContext()
}
return image

}

我想把顶部做得更大,并保持下半部分的大小相同。我不想屏蔽或剪切原始图像的某些部分。我想通过拉伸而不是遮罩来使图像更大。我在这个网站上没有看到任何解释如何做到这一点或如果可能的话。

【问题讨论】:

  • 假设“绿色”部分是图像——即使不是——如果没有某种掩蔽,这可能是不可能的。从 4 点四边形到 5 点六边形(原文如此?)几乎必须包括遮罩或裁剪。您是否有机会为您正在尝试做的事情添加更多细节?现在,我最好的想法是以某种方式使用 CIPerspectiveCorrection - 但即使这样也使用 4 点四边形。 (您甚至可能需要深入研究几何细节。)
  • 不关心是否使用掩码。我只是不想剪掉图像的任何部分。
  • 仔细想想,透视校正也无济于事。您需要一种通过拖动单个点来“拉伸”图像的方法。我确信它可以完成 - 但它很可能需要像素级别的 OpenGL 脚本语言 (GLSL)。我做了一些编码,但不是那个特别的东西。如果你知道它,它可能需要所谓的 CI 扭曲内核,因为你需要知道“拉伸”的周围像素。希望我能提供更多帮助(你给了我一个应用程序的想法)!希望其他人的答案比我好得多。
  • 杰森,你的例子解释性不够。假设图像不是简单的固定颜色,而是像代码中的图像更复杂的东西,你期望得到什么?例如,如果原始图像很简单 linear gradient 并且新的中上点位于原始图像的 2 倍高度,那么新图像应该是什么样子?在原始顶部边框的中间会是黄色(渐变的中间)吗?
  • @SergGr 使用您的线性渐变示例,所有可能发生的情况是相同的线性结构会更大。我看起来你的盒子是 300 x 300。我试图只在 300 x 500 的五边形中制作同样的东西。我主要是在尝试遵循这个例子,但这是在 swift 2 stackoverflow.com/questions/33163317/…

标签: ios swift swift3 imageview shape


【解决方案1】:

如果您不想使用蒙版进行裁剪,您将看到非常奇怪的扭曲图像。如果您真的确定这是您想要的,您可以使用https://github.com/Ciechan/BCMeshTransformView 首先将所有点向下移动,然后对其进行动画处理以仅将中心点向上移动。类似:

BCMeshVertex vertices[] = {
    {.from = {0.0, 0.0}, .to= {0.0, 0.5, 0.0}},
    {.from = {1.0, 0.0}, .to= {1.0, 0.5, 0.0}},
    {.from = {1.0, 1.0}, .to= {1.0, 1.0, 0.0}},
    {.from = {0.0, 1.0}, .to= {0.0, 1.0, 0.0}},
};

然后当你想把它变成房子时,将向量更新为:

BCMeshVertex vertices[] = {
    {.from = {0.0, 0.0}, .to= {0.0, 0.5, 0.0}},
    {.from = {0.5, 0.0}, .to= {0.0, 0.0, 0.0}},
    {.from = {1.0, 0.0}, .to= {1.0, 0.5, 0.0}},
    {.from = {1.0, 1.0}, .to= {1.0, 1.0, 0.0}},
    {.from = {0.0, 1.0}, .to= {0.0, 1.0, 0.0}},
};

这会产生一个奇怪的网格,像Warp \ bend effect on a UIView? 这样的扭曲效果——我很确定这看起来会非常非常难看。但这就是你所要求的。 (有一个更简单的解决方案,使用 CAShapeLayer 来屏蔽图像)。

【讨论】:

【解决方案2】:

你可以参考一下

https://www.innofied.com/implementing-image-masking-in-ios/

当有任何问题时,我会为此提供代码,但是,现在你表明对你有没有帮助..我尽我所能..

示例:

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var imageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let image = UIImage(named: "image.gif")
        let maskingImage = UIImage(named: "mask-image.gif")
        imageView.image = maskImage(image: image!, mask: maskingImage!)
    }

        func maskImage(image:UIImage, mask:(UIImage))->UIImage{

        let imageReference = image.cgImage
        let maskReference = mask.cgImage

        let imageMask = CGImage(maskWidth: maskReference!.width,
                                height: maskReference!.height,
                                bitsPerComponent: maskReference!.bitsPerComponent,
                                bitsPerPixel: maskReference!.bitsPerPixel,
                                bytesPerRow: maskReference!.bytesPerRow,
                                provider: maskReference!.dataProvider!, decode: nil, shouldInterpolate: true)

        let maskedReference = imageReference!.masking(imageMask!)

        let maskedImage = UIImage(cgImage:maskedReference!)

        return maskedImage
    }
}

【讨论】:

    【解决方案3】:

    我真的没有看到在新的 BezierPath 中再创建一个点并使用相同的 fillColor、Stroke 等绘制新图像的问题。 您可以使用像这样的扩展...

    public class func shapeImage(with bezierPath: UIBezierPath, size: CGSize, fillColor: UIColor? = UIColor.clear,
                                 strokeColor: UIColor? = nil, strokeWidth: CGFloat = 0.0) -> UIImage! {
    
        UIGraphicsBeginImageContext(size)
        let context = UIGraphicsGetCurrentContext()
        var image = UIImage()
        if let context = context {
            context.saveGState()
            context.addPath(bezierPath.cgPath)
    
            if let strokeColor = strokeColor {
                strokeColor.setStroke()
                context.setLineWidth(strokeWidth)
            } else {
                UIColor.clear.setStroke()
            }
    
            fillColor?.setFill()
            context.drawPath(using: .fillStroke)
    
            image = UIGraphicsGetImageFromCurrentImageContext()!
            context.restoreGState()
            UIGraphicsEndImageContext()
        }
        return image
    }
    

    【讨论】:

    • 我根据您的建议编辑了问题,但它没有做任何事情。我不知道如何调用该函数。
    • 对我来说,仍然不清楚您是想在 CUSTOM 位置上的 IMAGE 上实现拉伸,还是在贝塞尔路径绘制的 SHAPE 上实现拉伸?!
    • 我想在自定义位置上拉伸图像。
    猜你喜欢
    • 2018-10-11
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 2019-03-28
    • 1970-01-01
    • 2020-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多