菜鸟教程小白 发表于 2022-12-12 13:24:57

iOS重绘图像以防止延迟解压导致图像更大


                                            <p><p>我注意到有些人在 <code>CGContext</code> 上重绘图像以防止延迟解压缩,这导致我们的应用出现错误。</p>

<p>错误是图像的大小声称保持不变,但 <code>CGImageDataProvider</code> 数据附加了额外的字节。</p>

<p>比如我们从网上下载了一张797x500的PNG图片,<code>AsyncImageView</code>重绘并返回重绘后的图片。</p>

<p>代码如下:</p>

<pre><code>UIImage *image = [ initWithData:data];
if (image)
{
    // Log to compare size and data length...
    NSLog(@&#34;BEFORE: %f %f&#34;, image.size.width, image.size.height);
    NSLog(@&#34;LEN%ld&#34;, CFDataGetLength(CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))));

    // Original code from AsyncImageView
    //redraw to prevent deferred decompression
    UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
    ;
    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Log to compare size and data length...
    NSLog(@&#34;AFTER:%f %f&#34;, image.size.width, image.size.height);
    NSLog(@&#34;LEN%ld&#34;, CFDataGetLength(CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage))));

    // Some other code...
}
</code></pre>

<p>日志显示如下:</p>

<pre><code>BEFORE: 797.000000 500.000000
LEN1594000
AFTER:797.000000 500.000000
LEN1600000
</code></pre>

<p>我决定将每个字节一个一个地打印出来,果然每行都附加了十二个<code>0</code>。</p>

<p>基本上,重绘导致图像数据成为 800x500 图像的数据。因此,当我们的应用想要查看第 <code>797 * 行 + 列</code>th 像素时,它正在查看错误的像素。</p>

<p>我们没有使用任何大图像,因此延迟解压不会造成任何问题,但如果我决定使用这种方法重绘图像,我可能会引入一个微妙的错误。</p>

<p>有没有人可以解决这个问题?还是这是 Apple 引入的 bug,我们真的无能为力?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>正如您所发现的,行被填充到方便的大小。这通常是为了使向量算法更有效。如果你打算以这种方式使用 <code>CGImage</code>,你只需要适应那个布局。您需要调用 <code>CGImageGetBytesPerRow</code> 来找出实际分配的字节数,然后根据该值调整偏移量 (<code>bytesPerRow * row + column</code>)。</p>

<p>这可能最适合您,但如果您需要摆脱填充,您可以通过创建自己的 <code>CGBitmapContext</code> 并渲染到其中来实现。如果您不熟悉它,那将是 Stack Overflow 的一个被广泛讨论的话题。例如:<a href="https://stackoverflow.com/questions/448125/how-to-get-pixel-data-from-a-uiimage-cocoa-touch-or-cgimage-core-graphics" rel="noreferrer noopener nofollow">How to get pixel data from a UIImage (Cocoa Touch) or CGImage (Core Graphics)?</a> </p></p>
                                   
                                                <p style="font-size: 20px;">关于iOS重绘图像以防止延迟解压导致图像更大,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/43669682/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/43669682/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: iOS重绘图像以防止延迟解压导致图像更大