简体   繁体   中英

Reading tiff Image from Oracle long raw by c# not working

I have a long raw column contains a tiff image which is saved by oracle form application, I'm trying to retrieve the image by c# and save it with no luck, the image is valid, but it display crappy drawing.

DataBase column definition

SIGNATURE     NOT NULL LONG RAW()  

C# Code

internal void save(string account) { 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();
        }

The saved image looks like由 c# 保存的图像

I built new oracle form and bound the image with the column, and it displayed correctly, any idea? 按 Oracle 形式

EDIT: I found that the image in Oracle database saved as Big-Endian byte order

After few days of understanding and finding solutions around, the following solved my problem, the code below convert to another type of image encoding also do converting to little-endian

Please note that, the code is using BitMiracle.LibTiff library,

        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;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM