由于历史原因,我们被迫一起使用Cairo和Imager。
从Cairo转换为Imager并由于某种原因将其转换回Imager会使颜色变得奇怪。
再次转换为Imager的原因是在此之后与另一个Imager对象结合。
# Create a yellow fill image as Cairo object.
# And output as a png file.
my $testSurface = Cairo::ImageSurface->create(
'argb32',
$width,
$height
);
my $testContext = Cairo::Context->create($testSurface);
$testContext->rectangle(0, 0, $width, $height);
$testContext->set_source_rgba(1.0, 1.0, .0, 1);
$testContext->fill();
# This is a yellow png file.
$testSurface->write_to_png("output/fill_yellow.png");
# Convert the Cairo object to an Imager object.
my $testData = $testSurface->get_data;
my $testImager = Imager->new(
xsize => $width,
ysize => $height,
channels => 4,
);
my $testRes = $testImager->read(
data => $testData,
type => "raw",
xsize => $width,
ysize => $height,
raw_datachannels => 4,
raw_storechannels => 4,
raw_interleave => 0,
);
# Output Imager object as a PNG file.
# ! This PNG file becomes blue unexpectedly
$testRes->write(
file => "output/fill_yellow_imager.png",
type => "png"
);
答案 0 :(得分:4)
Cairo正在使用ARGB作为其原始格式,而Imager正在使用RGBA。它们之间的差异是样本存储在每个像素中的顺序。开罗也使用预乘alpha,而Imager使用非预乘alpha。两个图书馆似乎没有任何选择来改变这些事情。
通过重新排序原始图像数据中的字节,可以相当容易地修复样本排序事物,但是预乘事物开始进入不值得打扰的领域。因此,我建议您只需在开罗中保存PNG文件并将其加载到Imager中。它可能稍慢,但很容易理解并认识到它是正确的。
下面:在我意识到预乘的alpha问题之前,建议交换字节顺序的本答案的先前版本的代码:
for (my $i = 0 ; $i < length($testData) ; $i += 4) {
substr($testData, $i, 4,
substr($testData, $i+1, 3) . substr($testData, $i, 1)
);
}
我不建议使用它。