问题描述
这是另一个问题的简短测试,我尝试使用 ImageAttributes.SetRemapTable()
替换图像中的颜色。我发现 Graphics.DrawImage()
也会改变其他颜色,这些颜色不属于颜色映射。
因此我在 Graphics.DrawImage()
上创建了一个小测试。
我希望两个保存的图像是相同的:
var bitmap = new Bitmap (1,1,PixelFormat.Format32bppArgb);
bitmap.SetPixel(0,Color.FromArgb(10,10,10));
bitmap.Save (@"bitmap1.png",ImageFormat.Png);
var bitmap2 = new Bitmap (1,PixelFormat.Format32bppArgb);
var graphics = Graphics.FromImage(bitmap2);
graphics.DrawImage(bitmap,Point.Empty);
bitmap2.Save (@"bitmap2.png",ImageFormat.Png);
bitmap1
中像素的 ARGB 为 10,10
。bitmap2
中像素的 ARGB 为 10,0
。
为什么 DrawImage()
没有像我预期的那样绘制?
我怎样才能得到预期的结果?
我不想创建自己的颜色替换方法;我希望 .net 的颜色映射正常工作。
编辑
我做了另一个测试,同样的 1 像素图像,但我使用了 ARGB 10,10
,而不是 ARGB 100,100,100
。输出像素现在具有 ARGB 100,99,99
。
在我看来,这像是 GDI+ 或 .Net 中的错误,但绝对不是预期的计算输出。
而且,为了确保它不是由 1 个像素的宽度和高度引起的另一项改进,我改为
var bitmap = new Bitmap (5,5,PixelFormat.Format32bppArgb);
bitmap.SetPixel(2,2,Color.FromArgb(100,100));
再一次,输出像素是 ARGB 100,99
。
这现在看起来像是舍入错误,但上面的 10,0
绝对不是舍入错误。
编辑 2
现在看起来都像是舍入错误:像素颜色的计算似乎舍入了例如在除法之后(可能除以整数),所以舍入误差乘以另一个乘法。
此测试使用 16x16 和 RGB 20,255 和 Alpha 0(左上角)到 255(右下角)。
Beyond Compare中bitmap1(左)和bitmap2(右)的比较,底部的结果(结果图像的对比度增加),表明在低alpha时差异很大,在高alpha时在RGB中向1或0减小:
示例值:
Pixel 0|0: Left = ARGB 0,20,255; Right = ARGB 0,0.
Pixel 1|0: Left = ARGB 1,255; Right = ARGB 1,255.
Pixel 2|0: Left = ARGB 2,255; Right = ARGB 2,127,255.
Pixel 3|0: Left = ARGB 3,255; Right = ARGB 3,85,255. (85 = 1/3*255 => obvIoUsly division by alpha 3)
Pixel 3|0: Left = ARGB 4,255; Right = ARGB 4,255. (127 = 2/4*255 => obvIoUsly division by alpha 4)
Pixel 5|0: Left = ARGB 5,255; Right = ARGB 5,102,255. (102 = 2/5*255 => obvIoUsly division by alpha 5)
Pixel 15|0: Left = ARGB 15,255; Right = ARGB 15,17,255. (17 = 1/15*255 => obvIoUsly division by alpha 15)
Pixel 14|15: Left = ARGB 254,255; Right = ARGB 254,254.
Pixel 15|15: Left = ARGB 255,255; Right = ARGB 255,255.
是否有其他方法可以绘制部分透明的图像?
解决方法
问题背后的目的是交换图像中的颜色。交换的颜色包括透明度(alpha 因此,最后,我创建了自己的方法:
const connection = await db.connection();
try {
await connection.query("START TRANSACTION");
await connection.query('delete from X where id=?',[bar.id]);
await connection.query('INSERT INTO X (...) values (...)
await connection.query("COMMIT");