【问题标题】:Swift CGContext Aspect FitSwift CGContext Aspect Fit
【发布时间】:2016-10-11 22:17:07
【问题描述】:

我有两个图像视图,一个带有图像,另一个带有使用 CGContext 方法定义的图像,两者都具有相同的图像大小和图像视图大小,彼此叠加。在情节提要中,我可以将两个图像视图都设置为“Aspect Fit”,这样不同设备上的用户仍然可以看到图像。但是,当我在覆盖的第二个图像视图上绘制某些东西时,它不会相应地缩放它(或相对于第一个图像视图,即使它们的大小相同)。如何使重叠图像视图中的第二张图像与下图具有相同的比例?

示例代码:

import CoreGraphics
import UIKit

class Map: UIViewController, UIScrollViewDelegate {
    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var drawnImageView: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.scrollView.minimumZoomScale = 1.0
        self.scrollView.maximumZoomScale = 6.0

        let data = grabData()
        print(data!)

        var img = UIImage(named: "floor1")
        print(img!.size)
        imageView.image = img

        img = draw(imageView.bounds.size, data: data!)
        print(img!.size)
        drawnImageView.image = img
        for c in drawnImageView.constraints {
            if c.identifier == "constraintImageHeight" {
                c.constant = img!.size.height * drawnImageView.bounds.width / img!.size.width;
                break;
            }
        }
    }
}

func draw(img: UIImage) -> UIImage {
    UIGraphicsBeginImageContext(img.size)
    let context = UIGraphicsGetCurrentContext()

    // Drawing
    let color = UIColor(red: 0.67, green: 0.4, blue: 0.56, alpha: 1)
    CGContextSetStrokeColorWithColor(context, color.CGColor)
    CGContextSetLineWidth(context, 2.0)

    var y = 0
    for _ in 0..<100 {
        let b = CGRect(origin: CGPoint(x: 0, y: y), size: CGSize(width: 1200, height: 1))
        CGContextStrokeRect(context, b)
        y += 30
    }

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

更新 1:
(在'//绘图'之后替换) 如果您使用 iPhone 5 模拟器加载,它不会像在 iPhone 6 模拟器中那样显示在与照片相关的相同位置。

func draw(size: CGSize, data: [TotalLine]) -> UIImage {
    UIGraphicsBeginImageContext(size)
    let context = UIGraphicsGetCurrentContext()
    let screen: CGRect = UIScreen.mainScreen().bounds
    let x = screen.size.width, y = screen.size.height

    // Drawing
    //let color = UIColor(red: 0.67, green: 0.4, blue: 0.56, alpha: 1)
    let color = UIColor.redColor()
    CGContextSetStrokeColorWithColor(context, color.CGColor)
    CGContextSetLineWidth(context, 2.0)

    let line = CGRect(origin: CGPoint(x: (x/16), y: (y*0.502)), size: CGSize(width: (x/20), height: 2))
    CGContextStrokeRect(context, line)
    let test = CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: x, height: y))
    CGContextStrokeRect(context, test)

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

更新 2:
iPhone 6:

iPhone 5:

我想让那条红线出现在房间之间,就像 iPhone 6 的截图一样。在 iPhone 5 中,它略低。

更新 3:
打印图像视图:
iPhone 5:

绘制的图像视图:frame = (0 0; 600 536); 图像视图:frame = (0 0; 600 536);

iPhone 6:

绘制的图像视图: frame = (0 0; 600 536); 图像查看: frame = (0 0; 600 536);

【问题讨论】:

  • 您更新的代码中的xy 是什么?没有提供定义或初始值。您是否完全删除了for 循环?与 iPhone 6 相比,iPhone 5 到底有什么问题?
  • 在调用 draw 方法之前打印两个设备的 imageView 框架并在此处提供输出
  • 已更新,更新 3
  • @alexburtnik 知道发生了什么吗?
  • 我正在考虑它,但现在没有想法,如果不幸的是我无法重现。如果您有一个测试项目遇到此问题,请与我分享,我可能会修复它

标签: ios swift core-graphics cgcontext


【解决方案1】:

尝试替换这一行:

UIGraphicsBeginImageContext(img.size)

用这个:

UIGraphicsBeginImageContextWithOptions(img.size, false, UIScreen.main.scale)

不清楚为什么要使用 100 和 1200 硬编码值。如果您的原始图像足够大(高于 3000 或宽于 1200),则您的线条不会填满整个图像。此外,您实际上并不需要原始图像来创建叠加层。你只需要知道大小,对吧?试试这个方法:

func createLinesImage(size: CGSize) -> UIImage {
    UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
    let context = UIGraphicsGetCurrentContext()!

    let color = UIColor(red: 0.67, green: 0.4, blue: 0.56, alpha: 1)
    context.setStrokeColor(color.cgColor)
    context.setLineWidth(2.0)

    var y = CGFloat(0)
    while y < size.height {
        let lineRect = CGRect(x: 0, y: y, width: size.width, height: 1)
        context.stroke(lineRect)
        y += 30
    }

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

现在,如果您只想在原始图像上画线,请像这样调用您的方法:

imageView2.image = createLinesImage(size: originalImage.size)

如果您需要用线条填充整个 imageView,即使您的原始图像有空白区域,请使用此行:

imageView2.image = createLinesImage(size: imageView2.bounds.size)

【讨论】:

  • UIScreen 没有成员“main”
  • 你用的是swift 2吗?试试 UIScreen.mainScreen().scale 然后
  • 不起作用。它最终所做的只是将绘制的图像移动数百像素......
  • 如果您添加问题的屏幕截图会很棒。我试过你的代码,它看起来就像你实现它一样。下面的原始图像和一个以编程方式创建的图像,其中包含一堆水平线。这真的是你所期望的吗? snag.gy/j6woR3.jpg
  • 是的,我只是把水平线放进去,这样更容易查看更改。它基本上是一个室内地图系统,我必须在建筑物的走廊上画线。 (与之前相同的代码)pasteboard.co/e9vmls8T2.png
猜你喜欢
  • 1970-01-01
  • 2011-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多