【问题标题】:Reading tiff Image from Oracle long raw by c# not working通过 c# 从 Oracle long raw 读取 tiff 图像不起作用
【发布时间】:2018-09-03 11:59:39
【问题描述】:

我有一个很长的原始列包含一个由 oracle 表单应用程序保存的 tiff 图像,我正在尝试通过 c# 检索图像并保存它没有运气,图像是有效的,但它显示蹩脚的绘图。

数据库列定义

SIGNATURE     NOT NULL LONG RAW()  

C#代码

内部无效保存(字符串帐户) { var commonAccount = new List();

        using (OracleConnection cn = new OracleConnection(ConfigurationManager.ConnectionStrings["-----"].ConnectionString))
        {
            var imgCmd = new OracleCommand("select SIGNATURE, number, code, name  from table_name where number = ***** and code = *****", cn);
            imgCmd.InitialLONGFetchSize = -1;
            cn.Open();

            var reader = imgCmd.ExecuteReader();
            if (reader.Read())
            {
                //var v1 = reader[0];
                var v2 = reader[1].ToString();
                var v3 = reader[2].ToString();
                var v4 = reader[3].ToString();

                OracleBinary imgBinary = reader.GetOracleBinary(0);

                // Get the bytes from the binary obj
                byte[] imgBytes = imgBinary.IsNull ? null : imgBinary.Value;

                var newData = Convert.ToBase64String(imgBytes);


                MemoryStream stream = new MemoryStream();
                stream.Write(imgBytes, 0, imgBytes.Length);
                Bitmap bm = new Bitmap(stream);
                bm.Save("d:\\image.tif", System.Drawing.Imaging.ImageFormat.Tiff);
            }

            reader.Close();
        }

保存的图像看起来像

我建立了新的 oracle 表单并将图像与列绑定,并且它正确显示,知道吗?

编辑: 我发现Oracle数据库中的图像保存为Big-Endian字节顺序

【问题讨论】:

  • 我无法重现此错误。这是我所做的:1)创建了一个包含单个字段的表; 2)插入带有图像数据的单行; 2) 根据您的代码创建this program。代码运行良好,正确的图像保存在D:\image.tiff。我究竟做错了什么?你能帮我重现你的问题吗?
  • 您的示例由两部分组成:1)数据库访问; 2) 字节数组操作。也许,您可以确定其中哪一个有问题。为此,您需要将imgBytes 的内容与数据库中的实际字节进行比较。如果字节值不匹配,您将能够删除位图操作并专注于数据库访问(MCVE 会有所帮助。)
  • 你有没有通过oracle表单将图片保存到oracle?或者从.net方面,我不确定oracle表单图像组件在将图片保存到数据库时是否对图片有一些魔力,比如压缩?
  • 不,我只是用 SQLDeveloper 将图像直接插入到数据库中。然后我能够验证 C# 代码是否正常工作。不确定 Oracle Forms,检查数据库中实际存储的内容是有意义的。
  • 将此文本插入长原始列

标签: c# oracle oracleforms


【解决方案1】:

经过几天的了解和寻找解决方案,以下解决了我的问题,下面的代码转换为另一种类型的图像编码也转换为little-endian

请注意,代码使用BitMiracle.LibTiff库,

        private string GetBase64Data(byte [] image)
    {
        var data = string.Empty;
        using (MemoryStream ms = new MemoryStream(image))
        {
            using (Tiff tif = Tiff.ClientOpen("in-memory", "r", ms, new TiffStream()))
            {
                // Find the width and height of the image
                FieldValue[] value = tif.GetField(TiffTag.IMAGEWIDTH);
                int width = value[0].ToInt();

                value = tif.GetField(TiffTag.IMAGELENGTH);
                int height = value[0].ToInt();

                // Read the image into the memory buffer
                int[] raster = new int[height * width];
                if (!tif.ReadRGBAImage(width, height, raster))
                {
                    return data;
                }

                using (Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb))
                {
                    Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);

                    BitmapData bmpdata = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                    byte[] bits = new byte[bmpdata.Stride * bmpdata.Height];

                    for (int y = 0; y < bmp.Height; y++)
                    {
                        int rasterOffset = y * bmp.Width;
                        int bitsOffset = (bmp.Height - y - 1) * bmpdata.Stride;

                        for (int x = 0; x < bmp.Width; x++)
                        {
                            int rgba = raster[rasterOffset++];
                            bits[bitsOffset++] = (byte)((rgba >> 16) & 0xff);
                            bits[bitsOffset++] = (byte)((rgba >> 8) & 0xff);
                            bits[bitsOffset++] = (byte)(rgba & 0xff);
                        }
                    }

                    System.Runtime.InteropServices.Marshal.Copy(bits, 0, bmpdata.Scan0, bits.Length);
                    bmp.UnlockBits(bmpdata);

                    MemoryStream ims = new MemoryStream();
                    bmp.Save(ims, ImageFormat.Bmp);
                    data = Convert.ToBase64String(ims.ToArray());
                }
            }
        }

        return data;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多