You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何基于资源图片生成并绘制图像矩阵?现有实现存疑

把资源图像转成图像矩阵的正确实现方式

嘿,你的思路方向是对的,但还差几个关键步骤才能拿到有效的图像矩阵——首先得把资源里的foodWorld图像画到你创建的Bitmap里,不然你现在的Bitmap只是个空白画布,根本取不到像素值。下面一步步给你理清楚:

第一步:先确认资源图像加载正常

先加个小判断,避免资源加载失败导致后续报错:

Image foodWorld = Resources.orange;
if (foodWorld == null)
{
    throw new InvalidOperationException("资源里的orange图像没找到或者加载失败啦");
}

第二步:灵活设置Bitmap尺寸(可选)

你现在写死了400x300,如果想保留原图像的比例和尺寸,建议直接用原图像的宽高:

// 替换固定尺寸为原图像的宽高,防止图像拉伸变形
int width = foodWorld.Width;
int height = foodWorld.Height;
Bitmap b = new Bitmap(width, height);

第三步:填充图像矩阵的两种方法

方法一:简单直观的GetPixel(适合小图像)

先把资源图像绘制到Bitmap上,然后逐个像素获取RGB值填充矩阵:

// 用Graphics把原图像画到Bitmap上
using (Graphics g = Graphics.FromImage(b))
{
    g.DrawImage(foodWorld, 0, 0, b.Width, b.Height);
}

// 创建三维数组存每个像素的RGB值([行][列][RGB通道])
int[,,] imageMatrix = new int[height, width, 3];

for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        Color pixel = b.GetPixel(j, i);
        imageMatrix[i, j, 0] = pixel.R; // 红色通道
        imageMatrix[i, j, 1] = pixel.G; // 绿色通道
        imageMatrix[i, j, 2] = pixel.B; // 蓝色通道
    }
}

方法二:LockBits提升性能(适合大图像)

如果图像比较大,GetPixel会很慢,推荐直接操作内存里的像素数据,效率高很多:

// 锁定Bitmap的像素数据到内存
BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadOnly, b.PixelFormat);
IntPtr pixelPtr = bmpData.Scan0;

// 计算像素数据的总字节数
int totalBytes = Math.Abs(bmpData.Stride) * b.Height;
byte[] pixelBytes = new byte[totalBytes];

// 把内存里的像素数据复制到数组
System.Runtime.InteropServices.Marshal.Copy(pixelPtr, pixelBytes, 0, totalBytes);

// 填充矩阵(这里以24位RGB格式为例,每个像素占3字节,注意BGR顺序)
int[,,] imageMatrix = new int[height, width, 3];
for (int i = 0; i < height; i++)
{
    for (int j = 0; j < width; j++)
    {
        int byteIndex = i * bmpData.Stride + j * 3;
        imageMatrix[i, j, 2] = pixelBytes[byteIndex];     // B通道
        imageMatrix[i, j, 1] = pixelBytes[byteIndex + 1]; // G通道
        imageMatrix[i, j, 0] = pixelBytes[byteIndex + 2]; // R通道
    }
}

// 记得解锁Bitmap,不然会出问题
b.UnlockBits(bmpData);

关于你初始实现的正确性

你创建Bitmap的思路没问题,但漏掉了把原图像绘制到Bitmap这一步——没有这一步,你的Bitmap就是空白的,循环里根本拿不到有效像素值。补上绘制步骤后,整个流程就通顺啦。

内容的提问来源于stack exchange,提问作者Anthino Russo

火山引擎 最新活动