gpt4 book ai didi

macos - Mac OS X/iOS : How to write indexed PNG image using RGBA colours through CGImage?

转载 作者:行者123 更新时间:2023-12-03 17:22:34 27 4
gpt4 key购买 nike

我正在尝试使用 CGImageDestination 编写带有索引颜色和 alpha 值 (RGBA) 的 PNG 文件。就PNG specification而言这是一个颜色类型为 3 和 tRNS block 的图像。我从程序的单独部分获取索引矩阵和附加调色板。

我已经成功地编写了没有 alpha 值的索引图像(即只有不透明颜色)。如果我按照文档添加 alpha 值,生成的图像将不再使用颜色类型 3(调色板),而是变成完整的 RGBA 图像(颜色类型 6)。在实际的 PNG 文件中,alpha 值本质上附加到调色板条目。似乎没有办法创建显式 RGBA 色彩空间。

我可以直接使用libpng或其他PNG库来实现所需的编码。但是,如果可能的话,我宁愿只使用 CGImage 和 friend 。

TL;DR:如何使用 CGImage/CGImageDestination 生成带有 alpha 值的索引 PNG 文件?

两年前就已经提出了一个非常类似的问题( Create and write paletted RGBA PNG using NSImage ),但它谈到了 Cocoa 并且没有收到解决方案。

我的测试代码如下。如果在编译时定义了 USE_ALPHA ,则生成的图像将使用 alpha 值。否则就不会。

/* Compilation command (tested with Xcode 4.6.3 on Mac OS X 10.8.4):
*
* clang++ -std=c++11 -stdlib=libc++ -framework ApplicationServices -DUSE_ALPHA -o demo demo.cpp
*/

#include <utility>
#include <vector>
#include <array>

#include <ApplicationServices/ApplicationServices.h>

/* R, G, B */
const std::vector<std::array<std::uint8_t, 3>> colortable = {
{ 0xF0, 0x10, 0x10 },
{ 0x20, 0xF0, 0x20 },
{ 0x30, 0x30, 0xF0 },
{ 0xF0, 0xF0, 0x40 },
{ 0x50, 0xF0, 0xF0 },
};

/* Colour index, alpha */
const std::vector<std::uint8_t> data = {
3, 0x30,
2, 0x20,
1, 0x10,
0, 0x00,

4, 0x40,
3, 0x30,
2, 0x20,
1, 0x10,
};

void safeCfRelease(const ::CFTypeRef ref) {
if (ref != nullptr) {
::CFRelease(ref);
}
}

int main() {
const std::shared_ptr<const ::__CFURL>
url(::CFURLCreateWithFileSystemPath(nullptr, CFSTR("out.png"),
::kCFURLPOSIXPathStyle, false),
safeCfRelease);

const std::shared_ptr<::CGDataProvider>
prov_data(::CGDataProviderCreateWithData(nullptr, &data[0], data.size(), nullptr),
safeCfRelease);

const std::shared_ptr<::CGColorSpace>
gray(::CGColorSpaceCreateDeviceGray(), safeCfRelease),
rgb(::CGColorSpaceCreateDeviceRGB(), safeCfRelease),
indexed(::CGColorSpaceCreateIndexed(rgb.get(), colortable.size(),
reinterpret_cast<const unsigned char *>(&colortable[0])),
safeCfRelease);

const auto bitmap_info =
#ifdef USE_ALPHA
::kCGImageAlphaLast |
#else
::kCGImageAlphaNoneSkipLast |
#endif
::kCGBitmapByteOrderDefault;

const std::shared_ptr<::CGImage>
image(::CGImageCreate(/* width */ 4,
/* height */ 2,
/* bitsPerComponent */ 8,
/* bitsPerPixel */ 16,
/* bytesPerRow */ 8,
indexed.get(),
bitmap_info,
prov_data.get(), nullptr, false,
::kCGRenderingIntentDefault),
safeCfRelease);

const std::shared_ptr<::CGImageDestination>
dest(::CGImageDestinationCreateWithURL(url.get(), ::kUTTypePNG, 1, nullptr),
safeCfRelease);

::CGImageDestinationAddImage(dest.get(), image.get(), nullptr);
::CGImageDestinationFinalize(dest.get());
}

file 给出的不透明颜色描述(这也适用于使用 ImageMagick 生成的具有 tRNS block 的图像):

PNG image data, 4 x 2, 8-bit colormap, non-interlaced

使用 CGImageDestination 的 alpha 值描述:

PNG image data, 4 x 2, 8-bit/color RGBA, non-interlaced

最佳答案

不知道这是否有效,但是您尝试过 UIImagePNGRepresentation() 吗?

CGImage cgimg;   //initialize this with the CGImage that you want to be a PNG 
UIImage* image = [UIImage imageWithCGImage:cgimg];
NSData* pngData = UIImagePNGRepresentation(image);
CGImageRelease(cgimg);

希望这有帮助!

关于macos - Mac OS X/iOS : How to write indexed PNG image using RGBA colours through CGImage?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18158135/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com