web-dev-qa-db-ja.com

コアグラフィックスを使用してUIImageに長方形を描画する

Core Graphicsを使用して、UIImageの中央に長方形を配置して、おおよそ次のようにしようとしています。

enter image description here

これはこれまでの私のコードです:

func drawRectangleOnImage(image: UIImage) -> UIImage {
    let imageSize = image.size
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)
    let context = UIGraphicsGetCurrentContext()

    let rectangle = CGRect(x: 0, y: (imageSize.height/2) - 30, width: imageSize.width, height: 60)

    CGContextSetFillColorWithColor(context, UIColor.blackColor().CGColor)
    CGContextSetStrokeColorWithColor(context, UIColor.redColor().CGColor)
    CGContextSetLineWidth(context, 5)
    CGContextAddRect(context, rectangle)
    CGContextDrawPath(context, .Fill)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

送った画像の上に描いているのではなく、まったく新しい画像を作っているような気がします。全体が赤くなり、長方形は黒になります。黒い長方形が欲しいのですが、残りは画像と同じである必要があります。

私は何が間違っているのですか?

8
John Fda

送った画像の上に描いているのではなく、まったく新しい画像を作っているような気がします。

関係する感情はありません。それは文字通りこのコードが行うことです。

  1. 新しいコンテキストを作成します
  2. それに長方形を描きます
  3. コンテキストから画像を作成し、それを返します

手順1と2の間に、元の画像をコンテキストに描画する必要があります。

また、長方形をなでるのではなく、塗りつぶすだけなので、線幅や線の色を設定する必要はありません。 (何らかの理由で赤が表示されている場合は、このコードが原因ではありません。背景が赤の別のビューまたは画像がありますか?)

func drawRectangleOnImage(image: UIImage) -> UIImage {
    let imageSize = image.size
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)
    let context = UIGraphicsGetCurrentContext()

    image.draw(at: CGPoint.zero)

    let rectangle = CGRect(x: 0, y: (imageSize.height/2) - 30, width: imageSize.width, height: 60)

    CGContextSetFillColorWithColor(context, UIColor.black.CGColor)
    CGContextAddRect(context, rectangle)
    CGContextDrawPath(context, .Fill)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}

また、高レベルのUIKit APIを使用して描画することで、さらに簡素化できます。

func drawRectangleOnImage(image: UIImage) -> UIImage {
    let imageSize = image.size
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)

    image.draw(at: CGPoint.zero)

    let rectangle = CGRect(x: 0, y: (imageSize.height/2) - 30, width: imageSize.width, height: 60)

    UIColor.black.setFill()
    UIRectFill(rectangle)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage
}
21
Kurt Revis

KurtRevisの回答のObjectiveCバージョン

-(UIImage *)drawRectangleOnImage:(UIImage *)img rect:(CGRect )rect{
      CGSize imgSize = img.size;
      CGFloat scale = 0;
      UIGraphicsBeginImageContextWithOptions(imgSize, NO, scale);
      [img drawAtPoint:CGPointZero];
      [[UIColor greenColor] setFill];
      UIRectFill(rect);
      UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
      UIGraphicsEndImageContext();
      return newImage;
}
7
Prakash

あなたはそれを簡単に達成することができます

guard let img = actualImage else { return }
let croppedImage = img.cgImage!.cropping(to: CGRect(x: 0, y: 0, width: 50, height: 20))
let img = UIImage(cgImage: croppedImage!)
0