通过UIBezierPath裁剪后调整图像形状

时间:2017-03-15 12:37:45

标签: swift crop image-resizing

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

输入裁剪图像: enter image description here

输出图片:enter image description here

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

main

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

int main()
{
    srand(time(NULL));
    Grid board(10);
    size_t xValue = 0;
    size_t yValue = 0;

    // game loop. You could even abstract this behavior into another class
    while(true)
    {
        board.Print(std::cout);
        std::cout<<"\nEnter x value: ";
        if (!std::cin) // check for no input
            break;
        std::cin>>xValue;
        if (!std::cin) // check for end of input
           break;
        std::cout<<"Enter y value: ";
        std::cin>>yValue;
        if (!std::cin)
            break;
        board.SetValue(xValue, yValue, 0);

        // other game logic...
    }

    // print board one last time before exit
    std::cout << "Game over. Final board: \n";
    board.Print(std::cout);
}

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

错误是什么,解决方案是什么?

2 个答案:

答案 0 :(得分:0)

这样做。我们希望图像为矩形宽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;

    }

答案 1 :(得分:0)

哇。说实话?第一张图片非常接近我写的部分应用程序。 (这意味着赞美!它只是图像,而不是你在做什么。)

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

基本上,将你的UIImage / CGImage变成CIImage,将你的CGPoints转换为CIVectors,并调用过滤器。

(1)将图像转换为CIImage。

使用以下两行之一:

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

(2)将您的CGPoints转变为CIVectors。

CIImages起源于左下角而非左上角。 (换句话说,你需要翻转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的链接。