菜鸟教程小白 发表于 2022-12-12 19:51:51

ios - 如何将 HSB 颜色过滤器应用于 UIImage


                                            <p><p>我已经为 UIImage 着色项目苦苦挣扎了几天。
这个想法是,该应用程序将启动一组图像,我必须使用从 Web 服务检索到的值对这些图像进行着色。如果您愿意,可以选择某种主题。</p>

<p>与我一起工作的设计师给了我一张关于他所有 Photoshop 值的背景图片。</p>

<p>第一个问题是 Photoshop 使用 HSL 而 iOS 使用 HSB。所以第一个挑战是从 Photoshop 中转换值。</p>

<p>Photoshop HSL:-28(范围 -180 => +180)、100(范围 -100 => +100)、25(范围 -100 => +100)。</p>

<p>幸运的是我在网上找到了一些代码,<a href="https://gist.github.com/peteroupc/4085710" rel="noreferrer noopener nofollow">here it is</a> .</p>

<pre><code>//adapted from https://gist.github.com/peteroupc/4085710
- (void)convertLightnessToBrightness:(CGFloat)lightness withSaturation:(CGFloat)saturation completion:(void (^)(CGFloat, CGFloat))completion
{
    if (!completion)
      return; //What&#39;s the point of calling this method without a completion block!

    CGFloat brightness = 0.0f;
    CGFloat saturationOut = 0.0f;

    if (lightness &gt; 0.0f)
    {
      CGFloat lumScale = (1.0f - MAX((lightness - 0.5f), 0.0f) * 2.0f);
      lumScale = ((lumScale == 0) ? 0 : (1.0f / lumScale));

      CGFloat lumStart = MAX(0.0f, (lumScale - 0.5f));

      CGFloat lumDiv = (lumScale - lumStart);
      lumDiv = (lumStart + (saturation * lumDiv));

      saturationOut = ((lumDiv == 0) ? 0.0f : (saturation / lumDiv));
      brightness = (lightness + (1.0f - lightness) * saturation);
    }

    NSLog(@&#34;saturation: %0.2f - brightness: %0.2f&#34;, saturationOut, brightness);

    completion(saturationOut, brightness);
}
</code></pre>

<p>使用 <a href="http://www.workwithcolor.com/color-converter-01.htm" rel="noreferrer noopener nofollow">online converter</a>我验证了这个方法返回了好的值。<br/>
我需要更改范围(H:0->360,S:0->100,L:0->100)</p>

<p> <img src="/image/mHzMy.png" alt="color converter"/> </p>

<p>因此,HSL 152、100、62 给出 HSB 152、76、100。该方法返回 75 表示饱和度,100 表示亮度,所以我们很好。</p>

<p>接下来我需要将这些值应用于图像,所以这里是要更改的代码...</p>

<p>色调:</p>

<pre><code>#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0f * M_PI)

- (void)colorize:(UIImage *)input hue:(CGFloat)hueDegrees completion:(void(^)(UIImage *outputHue))completion
{
    if (!completion)
      return; //What&#39;s the point of calling this method without a completion block!

    CGFloat hue = DEGREES_TO_RADIANS(hueDegrees);

    NSLog(@&#34;degress: %0.2f | radian: %0.2f&#34;, hueDegrees, hue);

    CIImage *inputImage = ;

    //---
    CIFilter *hueFilter = ;
    ;
    forKey:kCIInputAngleKey];
    //---

    CIImage *outputImage = ;
    CIContext *context = ;
    CGImageRef cgimg = ];
    UIImage *outputUIImage = ;
    CGImageRelease(cgimg);

    completion(outputUIImage);
}
</code></pre>

<p>饱和度:</p>

<pre><code>- (void)colorize:(UIImage *)input saturation:(CGFloat)saturation completion:(void(^)(UIImage *outputSaturation))completion
{
    if (!completion)
      return; //What&#39;s the point of calling this method without a completion block!

    NSLog(@&#34;saturation: %0.2f&#34;, saturation);

    CIImage *inputImage = ;

    //---
    CIFilter *saturationFilter = ;
    ;
    forKey:@&#34;inputSaturation&#34;];
    //---

    CIImage *outputImage = ;
    CIContext *context = ;
    CGImageRef cgimg = ];
    UIImage *outputUIImage = ;
    CGImageRelease(cgimg);

    completion(outputUIImage);
}
</code></pre>

<p>亮度:</p>

<pre><code>- (void)colorize:(UIImage *)input brightness:(CGFloat)brightness completion:(void(^)(UIImage *outputBrightness))completion
{
    if (!completion)
      return; //What&#39;s the point of calling this method without a completion block!

    NSLog(@&#34;brightness: %0.2f&#34;, brightness);

    CIImage *inputImage = ;

    //---
    CIFilter *brightnessFilter = ;
    ;
    forKey:@&#34;inputBrightness&#34;];
    //---

    CIImage *outputImage = ;
    CIContext *context = ;
    CGImageRef cgimg = ];
    UIImage *outputUIImage = ;
    CGImageRelease(cgimg);

    completion(outputUIImage);
}
</code></pre>

<p>一切都放在一起:</p>

<pre><code>CGFloat hue = -28.0f; //152 in 360° range (180 - 28 = 152)
CGFloat saturation = 1.0f; //((100 + 100.0f) / 200.0f)
CGFloat lightness = 0.625f; //((25 + 100.0f) / 200.0f)

[self convertLightnessToBrightness:ligthness withSaturation:saturation completion:^(CGFloat saturationOut, CGFloat brightness) {

    //saturarationOut = 0.75f and brigthness = 1.0f
    [self colorize:input hue:hue completion:^(UIImage *outputHue) {

      [self colorize:outputHue saturation:saturationOut completion:^(UIImage *outputSaturation) {

            ;

      }];

    }];

}];
</code></pre>

<p>最后一个完成 block 只是将输出图像应用于 ImageView 。
现在是结果:</p>

<p>基础图片</p>

<p> <img src="/image/tCcmH.png" alt="base image"/> </p>

<p>着色(仅色调)</p>

<p> <img src="/image/Bo2F0.png" alt="hue only"/> </p>

<p>着色(色调和饱和度)</p>

<p> <img src="/image/k5kyZ.png" alt="hue and saturation"/> </p>

<p>着色(色调、饱和度和亮度)</p>

<p> <img src="/image/bbez5.png" alt="hue, saturation and brightness"/> </p>

<p>预期结果</p>

<p> <img src="/image/W5s33.png" alt="expected result"/> </p>

<p>如您所见,最终图像是全白的(亮度为 100%)。</p>

<p>我完全迷路了,我尝试了很多组合(在每个顺序中应用 H、S 和 B),我尝试过其他库,例如 <a href="https://github.com/jameswomack/iOS-Image-Filters" rel="noreferrer noopener nofollow">iOS-Image-Filters</a> ,没有任何成功。我还在 Stack Overflow 上阅读了很多问题。</p>

<p>链接:</p>

<ul>
<li> <a href="https://developer.apple.com/library/ios/documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html" rel="noreferrer noopener nofollow">Core Image Filter Reference</a> </li>
<li> <a href="https://stackoverflow.com/questions/11985150/cihueadjust-core-image-filter-setup" rel="noreferrer noopener nofollow">CIHueAdjust core image filter setup</a> </li>
<li> <a href="https://stackoverflow.com/questions/11555071/how-to-programmatically-change-the-hue-of-uiimage" rel="noreferrer noopener nofollow">How to programmatically change the hue of UIImage?</a> </li>
<li> <a href="https://stackoverflow.com/questions/11765244/ios-values-for-cifilter-hue-from-photoshop" rel="noreferrer noopener nofollow">iOS: Values for CIFilter (Hue) from Photoshop</a> </li>
</ul>

<p>有人成功地将 HSL/HSB 值应用于 UIImages?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>最后,我们决定改变技术。
我现在使用半透明图像来应用具有所需颜色的混合模式。</p>

<p>关注 <a href="http://robots.thoughtbot.com/designing-for-ios-blending-modes" rel="noreferrer noopener nofollow">this post</a>我在 <code>UIImage</code> 上做了一个分类。</p>

<pre><code>- (UIImage *)tintedBackgroundImageWithColor:(UIColor *)tintColor
{
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
    ;
    CGRect bounds = CGRectMake(0, 0, self.size.width, self.size.height);
    UIRectFill(bounds);

    ;

    UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return tintedImage;
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何将 HSB 颜色过滤器应用于 UIImage,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/22168297/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/22168297/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何将 HSB 颜色过滤器应用于 UIImage