【问题标题】:Resize image shape after cropping by UIBezierPath通过 UIBezierPath 裁剪后调整图像大小
【发布时间】:2017-08-06 04:55:36
【问题描述】:

在我的项目中,我尝试使用 UIBezierPath 裁剪图像,并通过使用 CAShapeLayer 和 setMask 操作轻松完成。在我的裁剪操作之后,输出是:

输入裁剪图像:

输出图片:

现在,我正在尝试拉伸输出图像并制作这个矩形大小的图像。为此,我使用一个函数并获取数组中的所有像素颜色,不包括具有清晰颜色的像素。为此,我使用此功能:

public func getRGBAs(fromImage image: UIImage, x: Int, y: Int, count: Int) -> [UIColor] {

    var result = [UIColor]()

    // First get the image into your data buffer
    guard let cgImage = image.cgImage else {
        print("CGContext creation failed")
        return []
    }

    let width = cgImage.width
    let height = cgImage.height
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let rawdata = calloc(height*width*4, MemoryLayout<CUnsignedChar>.size)
    let bytesPerPixel = 4
    let bytesPerRow = bytesPerPixel * width
    let bitsPerComponent = 8
    let bitmapInfo: UInt32 = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue

    guard let context = CGContext(data: rawdata, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else {
        print("CGContext creation failed")
        return result
    }

    context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    var byteIndex = bytesPerRow * y + bytesPerPixel * x

    for _ in 0..<count {
        let alpha = CGFloat(rawdata!.load(fromByteOffset: byteIndex + 3, as: UInt8.self)) / 255.0
        let red = CGFloat(rawdata!.load(fromByteOffset: byteIndex, as: UInt8.self)) / alpha
        let green = CGFloat(rawdata!.load(fromByteOffset: byteIndex + 1, as: UInt8.self)) / alpha
        let blue = CGFloat(rawdata!.load(fromByteOffset: byteIndex + 2, as: UInt8.self)) / alpha
        byteIndex += bytesPerPixel

        let aColor = UIColor(red: red, green: green, blue: blue, alpha: alpha)

        if aColor != UIColor(red: 0, green: 0, blue: 0, alpha: 0){

            result.append(aColor)

        }

        result.append(aColor)

    }

    free(rawdata)

    return result
}

然后尝试创建新图像以获取矩形图像。这段代码是:

public func imageFromARGB32Bitmap(pixels:[UIColor], width:UInt, height:UInt)->UIImage {
    let bitsPerComponent:UInt = 8
    let bitsPerPixel:UInt = 32

    assert(pixels.count == Int(width * height))

    var data = pixels // Copy to mutable []
    let providerRef = CGDataProvider(
        data: NSData(bytes: &data, length: data.count * MemoryLayout<UIColor>.size)
    )

    let cgim = CGImage(
        width: Int(width),
        height: Int(height),
        bitsPerComponent: Int(bitsPerComponent),
        bitsPerPixel: Int(bitsPerPixel),
        bytesPerRow: Int(width) * Int(MemoryLayout<UIColor>.size),
        space: rgbColorSpace,
        bitmapInfo: bitmapInfo,
        provider: providerRef!,
        decode: nil,
        shouldInterpolate: true,
        intent: .defaultIntent
    )
    return UIImage(cgImage: cgim!)
}

但输出图像既不是实际图像也不是矩形。最终输出图像:

出了什么问题,解决办法是什么?

【问题讨论】:

    标签: swift crop image-resizing


    【解决方案1】:

    哇。诚实地?第一张图片非常接近我编写的部分应用程序。 (这是一种恭维!这只是图像,而不是你在做什么。)

    您可以使用名为 CIPerspectiveCorrection 的核心图像过滤器。

    基本上,将您的 UIImage/CGImage 转换为 CIImage,将您的 CGPoints 转换为 CIVectors,然后调用过滤器。

    (1) 将您的图像转换为 CIImage。

    使用下面这两行之一:

    let ciInput = CIImage(image: myUiImage)
    let ciInput = CIImage(cgImage: myCgImage)
    

    (2) 将您的 CGPoints 变成 CIVectors。

    CIImage 的来源是左下角而不是左上角。 (换句话说,你需要翻转 Y 坐标。这是一个示例:

    let uiTL = CGPoint(x: 50, y: 50)
    let uiTR = CGPoint(x: 75, y: 75)
    let uiBL = CGPoint(x: 100, y: 300)
    let uiBR = CGPoint(x: 25, y: 200)
    let topLeft = createVector(uiTL,ciImage)
    let topRight = createVector(uiTR,ciImage)
    let bottomLeft = createVector(uiBL,ciImage)
    let bottomRight = createVector(uiBL,ciImage)
    
    func createVector(_ point:CGPoint, _ image:CIImage) -> CIVector {
        return CIVector(x: point.x, y: image.extent.height - point.y)
    }
    

    (您可能需要对此进行测试以确保正确映射出点。我徒手输入了转换 - uiTL 可能需要转换为 bottomLeft,依此类推。)

    (3)调用CoreImage滤镜:

    func doPerspectiveCorrection(
        _ ciInput:CIImage,
        _ topLeft:AnyObject,
        _ topRight:AnyObject,
        _ bottomRight:AnyObject,
        _ bottomLeft:AnyObject)
        -> UIImage {
    
            Let ctx = CIContext(options: nil)
            let filter = CIFilter(name: "CIPerspectiveCorrection")
            filter?.setValue(topLeft, forKey: "inputTopLeft")
            filter?.setValue(topRight, forKey: "inputTopRight")
            filter?.setValue(bottomRight, forKey: "inputBottomRight")
            filter?.setValue(bottomLeft, forKey: "inputBottomLeft")
            filter!.setValue(image, forKey: kCIInputImageKey)
            cgOutput = context.createCGImage((filter?.outputImage)!, from: (filter?.ciOutput?.extent)!)
            ciInput = filter?.outputImage
            return UIImage(cgImage: cgImage)
    }
    

    这应该将图像裁剪和缩放到您拥有的 4 个 CGPoints。

    她是官方Apple documentation的链接。

    【讨论】:

      【解决方案2】:

      这样做。我们希望图像是一个矩形宽 x 高

        x0, x1, x2, x3;
        y0, y1, y2, y3; -- image corners
        rgba = your image
        image = output image
      
        for(y=0;y<height;y++)
          for(x=0;x<width;x++)
          {
             float xprime, yprime;
      
             xprime = bilerp(x0, x1, x2, x3, x/width, y/height);
             yprime = bilerp(y0, y1, y2, y3, x/width, y/height);
      
             xf = xprime - floor(xprime);
             yf = yprime - floor(yprime);
      
             // Now do bilerp again on the image pixels
             ix = floor(xprime);
             iy = floor(yprime)
      
             pix = bilerp(rgba[iy][ix], rgba[iy][ix+1], rgba[iy+1][ix], rgba[iy+1][ix+1], xf, yf);
      
             image[y][x] = pix;
      
          }
      

      【讨论】:

      • 感谢您的回答,但您的回答对我来说并不清楚,因为我是 ios 领域的新手。如果您详细解释您的代码,这将对我非常有帮助。 bilirp(, , , , ,) 是什么,rgba = 你的图像,image = 输出图像,高度和宽度的值是多少?
      猜你喜欢
      • 2013-03-01
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多