c# - 将字节数组保存为 Pgn 或 Jpg

标签 c# png jpeg

我读取了一个 Tiff 文件,我想制作一个图 block 并将其保存为 Png 或 Jpg。我成功地以 Tif 格式保存了这个过程,如所附代码所示,定义了 DO_TIFF。但我不能以 Jpeg 或 Png 格式做同样的事情。程序总是在注释指出的位置崩溃。我已经在 Internet 上阅读了各种指示,但我找不到我的错误。代码应该是 self 解释的。不同之处在于我在 Tif 情况下使用二维数组,而在 JPEG 情况下使用一维数组。

        private static void MakeTile(string Original,int X,int Y,int W,int H,string TileName)
        {
            using (Tiff input = Tiff.Open(Original, "r"))
            {
                int width = input.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
                int height = input.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
                int samplesPerPixel = input.GetField(TiffTag.SAMPLESPERPIXEL)[0].ToInt();
                int bitsPerSample = input.GetField(TiffTag.BITSPERSAMPLE)[0].ToInt();
                int photo = input.GetField(TiffTag.PHOTOMETRIC)[0].ToInt();
                Rectangle roi = new Rectangle(X*samplesPerPixel, Y, W * samplesPerPixel, H);

                int scanlineSize = input.ScanlineSize();

                int nz = roi.Width;

                if (roi.Left+nz > scanlineSize)
                {
                    nz = scanlineSize-roi.Left;
                }
#if DO_JPEG
                byte[] output = new byte[roi.Height * nz];
#endif

#if DO_TIFF
                byte[][] output = new byte[roi.Height][];
#endif
                byte[] buffer = new byte[scanlineSize];

                W = nz / samplesPerPixel;

                for (int i = roi.Top,k=0; i < roi.Bottom; ++i,k++)
                {
                    input.ReadScanline(buffer, i);
#if DO_TIFF
                    output[k] = new byte[nz];
#endif
                    for (int j=0;j<nz;j++)
                    {
#if DO_TIFF
                        output[k][j]= buffer[roi.Left + j];
#endif

#if DO_JPEG
                        output[j+k*nz] = buffer[roi.Left+j];
#endif
                    }
                }
#if DO_JPEG
                using (Image image = Image.FromStream(new MemoryStream(output)))// error here: Patrameter Not Valid
                {
                    image.Save("output.jpg", ImageFormat.Jpeg);  // Or Png
                }
#endif
#if DO_TIFF
                using (Tiff Foutput = Tiff.Open(TileName, "w"))
                {
                    Foutput.SetField(TiffTag.IMAGEWIDTH, W);
                    Foutput.SetField(TiffTag.IMAGELENGTH, H);
                    Foutput.SetField(TiffTag.SAMPLESPERPIXEL, samplesPerPixel);
                    Foutput.SetField(TiffTag.BITSPERSAMPLE, bitsPerSample);
                    Foutput.SetField(TiffTag.ROWSPERSTRIP, Foutput.DefaultStripSize(0));
                    Foutput.SetField(TiffTag.PHOTOMETRIC, photo);
                    Foutput.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);

                    // change orientation of the image
                    // output.SetField(TiffTag.ORIENTATION, Orientation.RIGHTBOT);

                    for (int i = 0; i < H; ++i)
                        Foutput.WriteScanline(output[i], i);
                }
#endif
            }

        }
    }

最佳答案

要将图像保存为 JPEG 或 PNG,您需要使用不同于将其保存为 TIFF 的方法。

执行此操作的一种方法是使用 System.Drawing.Bitmap 类。此类有一个以字节数组作为参数的构造函数,因此您可以将输出数组传递给构造函数以创建 Bitmap 对象。然后,您可以使用 Bitmap 类的 Save 方法将图像保存为 JPEG 或 PNG 格式的文件。

#if DO_JPEG
  using (var image = new Bitmap(W, H, PixelFormat.Format24bppRgb)) {
  var bmpData = image.LockBits(new Rectangle(0, 0, W, H), 
  ImageLockMode.WriteOnly, image.PixelFormat);

  var ptr = bmpData.Scan0;
  Marshal.Copy(output, 0, ptr, output.Length);
  image.UnlockBits(bmpData);
  image.Save("output.jpg", ImageFormat.Jpeg);
  }
#endif

要将图像保存为 PNG,您可以使用相同的代码,但将 ImageFormat.Jpeg 替换为 ImageFormat.Png。

假设输出数组包含 24 位 RGB 数据。

关于c# - 将字节数组保存为 Pgn 或 Jpg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74921681/

相关文章:

Three.js、自定义着色器和具有透明度的 png 纹理

c++ - 扫描 JPEG 文件以查找标记

c# - 如何在C#中使用资源和文件

c# - 如何将我的公共(public) IP 与 HttpListener 一起使用

php - 从客户端 DOM 序列化 SVG 的最佳方式是什么?

在 Dia 中导入位图

python - 如何将 EXIF/其他元数据插入存储在内存缓冲区中的 JPEG?

JPEG-XL:有多少种 VarDCT 实现?

c# - 复杂 RavenDb 对象中的延迟加载

javascript - 绘制 HighChart 的数据点数量是否有限制