You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成与原图同尺寸、同色彩占比的目标色彩图像?

问题描述

原始图像为名为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:35:56