如何生成与原图同尺寸、同色彩占比的目标色彩图像?
问题描述
原始图像为名为colorslevels1.jpg的色彩渐变图,包含16种指定的目标颜色。
我目前使用以下两个方法从图像中提取指定色彩,并将这些色彩生成新图像。
private List<Color> GetColors() { if (bmp != null) { List<string> targetColors = new List<string> { "#ff00fe", "#d00078", "#e10a12", "#fb3f00", "#ff7d01", "#ffa800", "#ffcf00", "#fefd19", "#7cff21", "#12f218", "#01d31c", "#00b02c", "#008c4d", "#00a09b", "#00c3c9", "#0165ef" }; bmp = new Bitmap(@"d:\Ffmpeg Capture\colorslevels1.jpg"); int width = bmp.Width; int height = bmp.Height; for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { Color c = bmp.GetPixel(i, j); string hexColor = ColorTranslator.ToHtml(c).ToLower(); // Convert to lowercase // Check if the lowercase hex color matches any of the target colors if (targetColors.Contains(hexColor)) { colors.Add(c); } } } bmp.Dispose(); // Save the bitmap with the colors once all colors are collected SaveColorsAsBitmap(colors, @"d:\test.bmp"); } return colors; }
此方法收集符合条件的颜色后,调用以下方法将色彩保存为位图:
private void SaveColorsAsBitmap(List<Color> colors, string filePath) { // Determine the dimensions of the bitmap int width = 200; // Set the desired width (adjust as needed) int height = colors.Count; // Set the height to the number of colors // Create a new transparent bitmap with the determined dimensions Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); using (Graphics g = Graphics.FromImage(bitmap)) { // Clear the background to transparent g.Clear(Color.Transparent); // Draw each color as a vertical line on the bitmap for (int i = 0; i < height; i++) { using (SolidBrush brush = new SolidBrush(colors[i])) { g.FillRectangle(brush, 0, i, width, 1); } } } // Save the bitmap as a PNG file (PNG supports transparency) bitmap.Save(filePath, ImageFormat.Png); // Dispose of the bitmap to release resources bitmap.Dispose(); }
在SaveColorsAsBitmap方法中,我将宽度值设为200,因为如果设为1的话,新位图中的色彩会太小难以看清。
当前生成的结果是一个宽度为200的竖条图像,每个目标颜色单独占一行,但图像尺寸和各色彩的占比与原始图像完全不一致。我希望保留当前的色彩顺序,同时让新图像的尺寸和各色彩占比与原图一致,该如何修改?
解决方案
问题核心是当前逻辑仅收集符合条件的颜色列表,然后将每个颜色单独绘制为一行,完全丢失了原始图像的像素位置和尺寸信息。要保留原图尺寸和色彩占比,需要直接在与原图尺寸一致的画布上处理,保留每个符合条件像素的原始位置,不符合的像素设为透明(或指定背景色)。
修改方案
1. 替换原方法,直接处理并生成目标图像
取消单独收集颜色列表的逻辑,改为遍历原图每个像素,在新图中保留符合条件的像素,其余设为透明。这样能严格对齐原图的尺寸和像素分布。
修改后的处理方法:
private void ProcessImageAndSave(string inputPath, string outputPath) { // 定义目标颜色列表 List<string> targetColors = new List<string> { "#ff00fe", "#d00078", "#e10a12", "#fb3f00", "#ff7d01", "#ffa800", "#ffcf00", "#fefd19", "#7cff21", "#12f218", "#01d31c", "#00b02c", "#008c4d", "#00a09b", "#00c3c9", "#0165ef" }; // 使用using自动释放位图资源,避免内存泄漏 using (Bitmap originalBmp = new Bitmap(inputPath)) { // 创建与原图尺寸完全一致的透明位图 using (Bitmap resultBmp = new Bitmap(originalBmp.Width, originalBmp.Height, PixelFormat.Format32bppArgb)) { using (Graphics g = Graphics.FromImage(resultBmp)) { // 初始化背景为透明 g.Clear(Color.Transparent); // 遍历原图的每个像素 for (int y = 0; y < originalBmp.Height; y++) { for (int x = 0; x < originalBmp.Width; x++) { Color pixelColor = originalBmp.GetPixel(x, y); string hexColor = ColorTranslator.ToHtml(pixelColor).ToLower(); // 如果是目标颜色,直接绘制到新图的对应位置 if (targetColors.Contains(hexColor)) { resultBmp.SetPixel(x, y, pixelColor); } // 非目标颜色保持透明,无需额外处理 } } } // 保存结果为PNG(支持透明) resultBmp.Save(outputPath, ImageFormat.Png); } } }
2. 调用方式
直接调用上述方法即可完成处理:
ProcessImageAndSave(@"d:\Ffmpeg Capture\colorslevels1.jpg", @"d:\test.png");
关键说明
- 生成的图像尺寸与原始图像完全一致,每个符合条件的像素位置和原图一一对应,色彩占比完全匹配。
- 非目标颜色的像素会被设为透明,若需要固定背景色,可将
g.Clear(Color.Transparent)替换为g.Clear(Color.XXX)(例如Color.White)。 - 使用
using语句自动管理资源,比手动调用Dispose更安全,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Daniel Lip
相关产品推荐
相关产品推荐

