我希望将图像插值为一种颜色,以便过渡看起来与此相似:
我认为这很容易,但似乎比我想象的要困难一些。我尝试过的事情:
我不确定这种效果是如何实现的。以下是像素如何改变5个随机非黑色像素的颜色:
╔══════════════════╦═════╦═════╦═════╦════════╦═══════╦═══════╦═════════╗
║ Sample.Iteration ║ R ║ G ║ B ║ H ║ S ║ V ║ X,Y ║
╠══════════════════╬═════╬═════╬═════╬════════╬═══════╬═══════╬═════════╣
║ 1.1 ║ 104 ║ 168 ║ 144 ║ 157.50 ║ 38.10 ║ 65.88 ║ 121,81 ║
║ 1.2 ║ 96 ║ 152 ║ 144 ║ 171.43 ║ 36.84 ║ 59.61 ║ 121,81 ║
║ 1.3 ║ 80 ║ 120 ║ 152 ║ 206.67 ║ 47.37 ║ 59.61 ║ 121,81 ║
║ 1.4 ║ 72 ║ 104 ║ 152 ║ 216.00 ║ 52.63 ║ 59.61 ║ 121,81 ║
║ 1.5 ║ 56 ║ 72 ║ 160 ║ 230.77 ║ 65.00 ║ 62.75 ║ 121,81 ║
║ 1.6 ║ 40 ║ 40 ║ 168 ║ 240.00 ║ 76.19 ║ 65.88 ║ 121,81 ║
║ ║ ║ ║ ║ ║ ║ ║ ║
║ 2.1 ║ 72 ║ 144 ║ 128 ║ 166.67 ║ 50.00 ║ 56.47 ║ 125,119 ║
║ 2.2 ║ 64 ║ 128 ║ 128 ║ 180.00 ║ 50.00 ║ 50.20 ║ 125,119 ║
║ 2.3 ║ 56 ║ 96 ║ 128 ║ 206.67 ║ 56.25 ║ 50.20 ║ 125,119 ║
║ 2.4 ║ 48 ║ 88 ║ 128 ║ 210.00 ║ 62.50 ║ 50.20 ║ 125,119 ║
║ 2.5 ║ 40 ║ 56 ║ 136 ║ 230.00 ║ 70.59 ║ 53.33 ║ 125,119 ║
║ 2.6 ║ 32 ║ 32 ║ 136 ║ 240.00 ║ 76.47 ║ 53.33 ║ 125,119 ║
║ ║ ║ ║ ║ ║ ║ ║ ║
║ 3.1 ║ 152 ║ 208 ║ 168 ║ 137.14 ║ 26.92 ║ 81.57 ║ 80,82 ║
║ 3.2 ║ 136 ║ 184 ║ 168 ║ 160.00 ║ 26.09 ║ 72.16 ║ 80,82 ║
║ 3.3 ║ 112 ║ 144 ║ 184 ║ 213.33 ║ 39.13 ║ 72.16 ║ 80,82 ║
║ 3.4 ║ 96 ║ 128 ║ 192 ║ 220.00 ║ 50.00 ║ 75.29 ║ 80,82 ║
║ 3.5 ║ 72 ║ 88 ║ 200 ║ 232.50 ║ 64.00 ║ 78.43 ║ 80,82 ║
║ 3.6 ║ 48 ║ 48 ║ 216 ║ 240.00 ║ 77.78 ║ 84.71 ║ 80,82 ║
║ ║ ║ ║ ║ ║ ║ ║ ║
║ 4.1 ║ 40 ║ 72 ║ 104 ║ 210.00 ║ 61.54 ║ 40.78 ║ 158,75 ║
║ 4.2 ║ 32 ║ 64 ║ 96 ║ 210.00 ║ 66.67 ║ 37.65 ║ 158,75 ║
║ 4.3 ║ 32 ║ 48 ║ 88 ║ 222.86 ║ 63.64 ║ 34.51 ║ 158,75 ║
║ 4.4 ║ 24 ║ 40 ║ 88 ║ 225.00 ║ 72.73 ║ 34.51 ║ 158,75 ║
║ 4.5 ║ 24 ║ 32 ║ 80 ║ 231.43 ║ 70.00 ║ 31.37 ║ 158,75 ║
║ 4.6 ║ 16 ║ 16 ║ 72 ║ 240.00 ║ 77.78 ║ 28.24 ║ 158,75 ║
║ ║ ║ ║ ║ ║ ║ ║ ║
║ 5.1 ║ 144 ║ 192 ║ 232 ║ 207.27 ║ 37.93 ║ 90.98 ║ 127,99 ║
║ 5.2 ║ 128 ║ 168 ║ 224 ║ 215.00 ║ 42.86 ║ 87.84 ║ 127,99 ║
║ 5.3 ║ 104 ║ 136 ║ 224 ║ 224.00 ║ 53.57 ║ 87.84 ║ 127,99 ║
║ 5.4 ║ 96 ║ 120 ║ 216 ║ 228.00 ║ 55.56 ║ 84.71 ║ 127,99 ║
║ 5.5 ║ 72 ║ 88 ║ 216 ║ 233.33 ║ 66.67 ║ 84.71 ║ 127,99 ║
║ 5.6 ║ 48 ║ 48 ║ 208 ║ 240.00 ║ 76.92 ║ 81.57 ║ 127,99 ║
╚══════════════════╩═════╩═════╩═════╩════════╩═══════╩═══════╩═════════╝
值得注意的是,每种RGB颜色似乎是8的倍数,减量或增量也是8的倍数。我无法想象它在这里做了什么样的插值。
我需要做的一件事就是能够选择一种随机颜色(比如橙色,粉红色,蓝色),并能够实现与随机颜色相似的插值。
答案 0 :(得分:3)
这是一种产生相当简单结果的方法。正如我在评论中所写的那样,也许应该研究更复杂的方法,但是对于这个例子,这似乎就是这样做的。
我添加了6个PictureBox来模仿你的截图。第一个加载您的第一张图片。
最后一个被赋予makeMonoChrome函数的结果,该函数使用ColorMatrix;这是通常的灰度代码的变体,它将目标颜色乘以矩阵。这里重要的是魔术数字,它包含3个通道的加权亮度。
您可能想要使用目标颜色;我认为(255,64,64,255)看起来更接近......
其他图像是通过mix2Bitmaps
方法生成的第一个和最后一个图像之间的直接插值创建的,该方法采用两个位图,第二个应该在结果中具有百分比。 (可以通过分别检查percent == 0
和percent == 100
并返回其中一个源位图的克隆来扩展此方法。)
这是我的结果:
private void Form1_Load(object sender, EventArgs e)
{
Color targetColor = Color.FromArgb(255, 48, 48, 216);
pictureBox6.Image = MakeMonoChrome ((Bitmap)pictureBox1.Image, targetColor);
pictureBox2.Image =
mix2Bitmaps((Bitmap)pictureBox1.Image, (Bitmap)pictureBox6.Image, 20);
pictureBox3.Image =
mix2Bitmaps((Bitmap)pictureBox1.Image, (Bitmap)pictureBox6.Image, 40);
pictureBox4.Image =
mix2Bitmaps((Bitmap)pictureBox1.Image, (Bitmap)pictureBox6.Image, 60);
pictureBox5.Image =
mix2Bitmaps((Bitmap)pictureBox1.Image, (Bitmap)pictureBox6.Image, 80);
}
Bitmap mix2Bitmaps(Bitmap bmp0, Bitmap bmp1, int percent)
{
Bitmap bmp2 = new Bitmap(bmp0.Width, bmp0.Height, PixelFormat.Format32bppArgb);
int Bpp = 4; // assuming an effective pixelformat of 32bpp
var bmpData0 = bmp0.LockBits( new Rectangle(0, 0, bmp0.Width, bmp0.Height),
ImageLockMode.ReadOnly, bmp0.PixelFormat);
var bmpData1 = bmp1.LockBits( new Rectangle(0, 0, bmp1.Width, bmp1.Height),
ImageLockMode.ReadOnly, bmp1.PixelFormat);
var bmpData2 = bmp2.LockBits( new Rectangle(0, 0, bmp2.Width, bmp2.Height),
ImageLockMode.ReadWrite, bmp2.PixelFormat);
int len = bmpData0.Height * bmpData0.Stride;
byte[] data0 = new byte[len];
byte[] data1 = new byte[len];
byte[] data2 = new byte[len];
Marshal.Copy(bmpData0.Scan0, data0, 0, len);
Marshal.Copy(bmpData1.Scan0, data1, 0, len);
Marshal.Copy(bmpData2.Scan0, data2, 0, len);
float pctD = (100f - percent) / 100f;
float pct = percent / 100f;
for (int i = 0; i < len; i += Bpp)
{
data2[i + 0] = (byte)(data0[i + 0] * pctD + data1[i + 0] * pct);
data2[i + 1] = (byte)(data0[i + 1] * pctD + data1[i + 1] * pct);
data2[i + 2] = (byte)(data0[i + 2] * pctD + data1[i + 2] * pct);
if (Bpp == 4) data2[i + 3] = 255;
}
Marshal.Copy(data2, 0, bmpData2.Scan0, len);
bmp0.UnlockBits(bmpData0);
bmp1.UnlockBits(bmpData1);
bmp2.UnlockBits(bmpData2);
return bmp2;
}
public static Bitmap MakeMonoChrome(Bitmap bmp0, Color tCol)
{
Bitmap bmp1 = new Bitmap(bmp0.Width, bmp0.Height);
using (Graphics g = Graphics.FromImage(bmp1) )
{
float tr = tCol.R / 255f;
float tg = tCol.G / 255f;
float tb = tCol.B / 255f;
ColorMatrix colorMatrix = new ColorMatrix( new float[][]
{
new float[] {.3f * tr, .3f * tg, .3f * tb, 0, 0},
new float[] {.59f * tr, .59f * tg, .59f * tb, 0, 0},
new float[] {.11f * tr, .11f * tg, .11f * tb, 0, 0},
new float[] {0, 0, 0, 1, 0},
new float[] {0, 0, 0, 0, 1}
});
ImageAttributes attributes = new ImageAttributes();
attributes.SetColorMatrix(colorMatrix);
g.DrawImage(bmp0, new Rectangle(0, 0, bmp0.Width, bmp0.Height),
0, 0, bmp0.Width, bmp0.Height, GraphicsUnit.Pixel, attributes);
}
return bmp1;
}