【问题标题】:How can I create temperature specific color chart in iOS如何在 iOS 中创建温度特定颜色图表
【发布时间】:2018-03-08 06:51:17
【问题描述】:

在这个问题上,我需要你们提供一些算法或逻辑上的帮助。如果这在某些方面是可能的......

所以我必须开发/编写一个接收温度值作为输入(C° 或 F°)的函数,并在这张图片中准确地返回与温度相对应的特定颜色。例如,如果我们输入 0C°,颜色值应该返回为青色(十六进制值:29eff6 或 RGB:41,239,246)

参考图片

我在不同的网站上进行了很多搜索,但没有找到与此相关的内容。有 1000K° 以上的 kelvin color 代码,这些与我的问题无关。

对此的任何帮助将不胜感激。

【问题讨论】:

  • 参考图像的出处是什么?制作这张照片的人可能也有关于它是如何制作的背景信息。
  • 是的,已经向图像提供商询问过。但是没有找到任何满意的答案。
  • 即使他们不能或不会告诉你,如果你能解释这是从哪里来的,以及他们为什么没有告诉你完整的故事,也许会帮助我们更好地了解你的情况。
  • 裁剪图像,使您只有颜色渐变,然后将输入映射到图像宽度的像素值(例如 -50°C => 0px,+55°C => 图像.width) 并读取图片该 x 位置处的颜色值。这样您就不需要任何图像是如何创建的信息,如果您想要不同的结果,您可以简单地更改它。
  • @d.felber 你能解释一下你的评论吗?然后将你的输入映射到图像宽度的像素值(例如-50°C => 0px,+55° C => image.width) 并读取图片该 x 位置处的颜色值。”

标签: ios algorithm colors logic temperature


【解决方案1】:

range.png:

这是我在评论中提到的简单/虚假解决方案的示例:

import UIKit


func mapValue(value: CGFloat, inMin: CGFloat, inMax: CGFloat, outMin: CGFloat, outMax: CGFloat) -> CGFloat {
    // when the input value is lower than `inMin` use `inMin`
    // when the input value is bigger than `inMax` use `inMax`
    let value = max(min(value, inMax), inMin)

    let div = inMax - inMin
    guard div > 0 else {
        return inMin
    }

    return (value - inMin) / div * (outMax - outMin) + outMin
}


func getColor(for degreesCelsius: CGFloat) -> UIColor {
    // your color-range-image
    let rangeImage = UIImage(named: "range.png")!

    // the size of your color-range-image
    let imageSize = rangeImage.size

    let inMin: CGFloat = -50 // the lowest value as seen from the image
    let inMax: CGFloat = 55 // the highest value as seen from the image

    // the mapped input value
    let mappedInput = mapValue(value: degreesCelsius,
                               inMin: inMin, inMax: inMax,
                               outMin: 0, outMax: imageSize.width - 1)

    // position of the pixel in the image whose color should be extracted
    let pos = CGPoint(x: mappedInput, y: 0)

    return rangeImage.getPixelColor(pos: pos)
}

// get the color of 37°C
let color = getColor(for: 37)

要在某个位置提取UIImageUIColor,您可以使用:

// taken from https://stackoverflow.com/a/40237504/4511639
extension UIImage {
    func getPixelColor(pos: CGPoint) -> UIColor {

        let pixelData = self.cgImage!.dataProvider!.data
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)

        let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4

        let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)

        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
}

【讨论】:

    【解决方案2】:

    您需要将温度转换为 RGB 颜色。为此,您可以使用:

    但是,您的图像建议您使用波长颜色而不是温度颜色:

    由于您的梯度与实际温度无关,因此只需使用链接中的代码。然后在温度和波长之间进行线性插值,例如:

    wavelength = 400 + (800-400)*(T-t0)/(t1-t0) [nm]
    

    其中 T 是您的温度,t0,t1 是梯度边缘温度,单位与 T 相同,例如:

    t0=-50C
    t1=+50C
    

    如果您使用t0,t1,您可能会左右移动颜色。您还可以使用任何其他插值,而不仅仅是线性。甚至像我在两个链接的 QA 中所做的那样插入图像 RGB。

    如果您想要真实的东西(您明确表示您不想要,但那些因为您的头衔而在这里冒险的人可能),那么真正的问题是如何将温度转换为 BV 指数。我现在找不到任何方程。我发现的唯一东西是

    equation:

    table:

        T[K]    BV
    O5  42 000  -0.33
    O9  34 000  -0.31
    B0  30 000  -0.30
    B2  20 900  -0.24
    B5  15 200  -0.17
    B8  11 400  -0.11
    A0  9 790   -0.02
    A2  9 000   0.05
    A5  8 180   0.15
    F0  7 300   0.30
    F2  7 000   0.35
    F5  6 650   0.44
    F8  6 250   0.52
    G0  5 940   0.58
    G2  5 790   0.63
    G5  5 560   0.68
    G8  5 310   0.74
    K0  5 150   0.81
    K2  4 830   0.91
    K5  4 410   1.15
    M0  3 840   1.40
    M2  3 170   1.49
    M5  3 170   1.64
    

    dependece graph::

    因此,您要么从表格/图形中插入它或 approximate,要么从方程中以代数方式计算它(对我来说看起来像二次方程)。

    如果我没有犯错的话:

    bv0=(+sqrt((729.0*T*T) + 52900000000.0) - (58*T) + 230000.0 ) / 46.0*T
    bv1=(-sqrt((729.0*T*T) + 52900000000.0) - (58*T) + 230000.0 ) / 46.0*T
    

    我的直觉告诉我bv0 是那个bv1 太消极了。但看起来 Wiki 方程只是 非常差 近似,所以它的逆方程更糟......

    最重要的是,如果您获得了对象和环境的特定参数,那么如果您想要更逼真的颜色,则需要通过添加散射和混合体色来更改颜色。

    【讨论】:

    • 我很确定我们正在考虑制作天气图而不是星图 - 正如您所暗示的那样,星星永远不会是紫色的。提问者只需要用一系列固定点做一些线性插值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2014-08-30
    相关资源
    最近更新 更多