1

我想在 C# 中拆分一个拆分的字符串。基本上,我想以数字的形式保存图像,这里是使用 GetPixel 将其保存到 C# 中的数字的代码

TextWriter textWriter = new StreamWriter(fileName);
for (int x = 0; x < bmp.Width; x++)
{
   for (int y = 0; y < bmp.Height; y++)
   {
     Color pixel = bmp.GetPixel(x, y);
     textWriter.Write(pixel.R + "," + pixel.G + "," + pixel.B + " ");
   }
}

这是一个可能的结果:252,255,192 252,255,192 252,255,192。像素用空格隔开,rgb 用逗号隔开。

问题是当我尝试再次将其转换为图像时,这是我当前获取像素 rgb 的代码。

TextReader textReader = new StreamReader(fileName);
string allLine = textReader.ReadLine();
string[] splitPixel = allLine.Split(' ');
string[] splitRGB = null;

for (int i=0; i<splitPixel.Length; i++) {
  splitRGB[i] = splitPixel[i].Split(',');
}

这是设置像素颜色的代码

 for (int x = 0; x < bmp.Width; x++)
 {
    for (int y = 0; y < bmp.Height; y++)
    {
       byte tempR, tempG, tempB = 0;
       tempR = Convert.ToByte(splitRGB[x]);
       tempG = Convert.ToByte(splitRGB[x+1]);
       tempB = Convert.ToByte(splitRGB[x+2]);
       Color pixel = Color.FromArgb(tempR,tempG,tempB);
       bmp.SetPixel(x, y, pixel);
    }
 }

现在它只告诉我这个错误“无法将类型'string []'隐式转换为'string'” splitRGB[i] = splitPixel[i].Split(',')

4

3 回答 3

1
string[] splitPixel = allLine.Split(' ');
string[] splitRGB = new string[splitPixel.Length * 3];

for (int i=0; i<splitRGB.Length; i+=3) {
  string[] splitted = splitPixel[i].Split(',');
  splitRGB[i] = splitted[0];
  splitRGB[i + 1] = splitted[1];
  splitRGB[i + 2] = splitted[2];
}

编辑:这是一个更好的版本:

您应该将图像的宽度和高度保存在文件中(即:2x2图像与4 * 1图像具有相同的文件格式),这里我建议您将它们保存在第一行width height

using (TextReader textReader = new StreamReader(fileName)){
    string sizeLine = textReader.ReadLine();
    if (sizeLine == null) 
        throw new /*UnexpectedData*/Exception("invalid file!");
    string[] widthHeightStr = sizeLine.Split(' ');
    if (widthHeightStr.Length != 2) 
        throw new /*UnexpectedData*/Exception("invalid file!");
    int width = int.Parse(widthHeightStr[0]);
    int height = int.Parse(widthHeightStr[1]);
    string pixelsLine = textReader.ReadLine();
    if (onlyLine == null) 
        throw new /*UnexpectedData*/Exception("invalid file!");
    string[] splitPixel = pixelsLine.Split(' ');
    var bmp = new Bitmap(width, height);
    for (int i=0; i<splitPixel.Length; i++) {
        string[] splitted = splitPixel[i].Split(',');
        if (splitted.Length != 3) 
            throw new /*UnexpectedData*/Exception("invalid file!");
        int tempR = int.Parse(splitted[0]);
        int tempG = int.Parse(splitted[1]);
        int tempB = int.Parse(splitted[2]);
        Color pixel = Color.FromArgb(tempR,tempG,tempB);
        bmp.SetPixel(i / width, i % width, pixel);
    }   
}

编辑:

using (TextWriter textWriter = new StreamWriter(fileName){
    textWriter.WriteLine(bmp.Width + " " + bmp.Height);
    for (int x = 0; x < bmp.Width; x++)
    {
        for (int y = 0; y < bmp.Height; y++)
        {
            Color pixel = bmp.GetPixel(x, y);
            textWriter.Write(pixel.R + "," + pixel.G + "," + pixel.B + " ");
        }
    }
}
于 2013-10-14T13:14:30.233 回答
1

错误只是简单地解释了您试图将一个数组(因为 split 返回一个数组)放在一个字符串中,因为 splitRGB[i] 是一个字符串,其中 assplitRGB[] = splitPixel[i].Split(',');splitRGB[i][] = splitPixel[i].Split(',');<-splitRGB[][] = new splitRGB[10][3]可以工作

所以你的代码:

for (int i=0; i<splitPixel.Length; i++) 
{
   splitRGB[i] = splitPixel[i].Split(',');
}

如果要将数组放入数组中,则需要像这样的多维数组:

string[][] splitRGB = new string[splitPixel.Length][3];

和 for 循环来获取你的 RGB 值 for (int i=0; i

for (int x = 0; x < bmp.Width; x++)
 {
    for (int y = 0; y < bmp.Height; y++)
    {
       byte tempR, tempG, tempB = 0;
       tempR = Convert.ToByte(splitRGB[x][0]);
       tempG = Convert.ToByte(splitRGB[x][1]);
       tempB = Convert.ToByte(splitRGB[x][2]);
       Color pixel = Color.FromArgb(tempR,tempG,tempB);
       bmp.SetPixel(x, y, pixel);
    }
 }

这些变化非常微妙,我感觉自己犯了一个错误(我从不使用多维数组,我尽可能多地创建结构或类的数组)

于 2013-10-14T13:51:05.753 回答
0

由于我不知道您如何处理位图,因此我向您介绍了另一种方法来将位图数据一次性放入文件并返回(您可以将其拆分以满足您的需求)。我替换了 setPixel 和 GetPixel 因为它们访问数据的方式太慢了,这将提供更快的结果:

//assume you have a class member variable of type bitmap called sourceBitmap.

BitmapData sourceData = sourceBitmap.LockBits(new Rectangle(0, 0,
                                    sourceBitmap.Width, sourceBitmap.Height),
                                    ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height];

Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length);

sourceBitmap.UnlockBits(sourceData);

File.WriteAllBytes(@"C:\..\..\test.txt", pixelBuffer);

//here is where you can split the code...

byte[] fs = File.ReadAllBytes(@"C:\..\..\test.txt");

Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height);

BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0,
                                    resultBitmap.Width, resultBitmap.Height),
                                    ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

Marshal.Copy(fs, 0, resultData.Scan0, fs.Length);
            resultBitmap.UnlockBits(resultData);

pictureBox1.Image = resultBitmap;
于 2013-10-14T15:30:15.543 回答