草庐IT

ios - Swift CGContext 切面匹配

coder 2023-09-16 原文

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

示例代码:

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:
打印 ImageView :
iPhone 5:

Drawn Image View: frame = (0 0; 600 536); Image View: frame = (0 0; 600 536);

iPhone 6:

Drawn Image View: frame = (0 0; 600 536); Image View: frame = (0 0; 600 536);

最佳答案

尝试替换这一行:

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)

关于ios - Swift CGContext 切面匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39987654/

有关ios - Swift CGContext 切面匹配的更多相关文章

  1. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  2. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

  5. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  6. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  7. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  8. ruby - rbenv 安装 ruby​​ 校验和不匹配 osx - 2

    我已经在mountainlion上成功安装了rbenv和ruby​​build。运行rbenvinstall1.9.3-p392结束于:校验和不匹配:ruby-1.9.3-p392.tar.gz(文件已损坏)预期f689a7b61379f83cbbed3c7077d83859,得到1cfc2ff433dbe80f8ff1a9dba2fd5636它正在下载的文件看起来没问题,如果我使用curl手动下载文件,我会得到同样不正确的校验和。有没有人遇到过这个?他们是如何解决的? 最佳答案 tl:博士;使用浏览器从http://ftp.rub

  9. ruby - 正则表达式将非英文字母匹配为非单词字符 - 2

    @raw_array[i]=~/[\W]/非常简单的正则表达式。当我用一些非拉丁字母(具体来说是俄语)尝试时,条件是错误的。我能用它做什么? 最佳答案 @raw_array[i]=~/[\p{L}]/使用西里尔字符进行测试。引用:http://www.regular-expressions.info/unicode.html#prop 关于ruby-正则表达式将非英文字母匹配为非单词字符,我们在StackOverflow上找到一个类似的问题: https://

  10. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

随机推荐