locked
Access OLE embedded images do not display in ASP.NET RRS feed

  • Question

  • User-2116945077 posted

    My project is connected to an external Access database. All I want it to do, is to display certain images that are associated with certain names (eg. the cover of a book).


    All I want my project to do, is to display everything from a certain table in a data-bound datalist. Everything else works; it returns my Authorname, the book's name, the plotline etc. but it refuses to display the images which have been embedded into the database as OLE DB objects (Embedded, not linked via OLE).


    Someone was so kind as to help me before and I saw that his example worked. 

    This is the code-behind that was given to me:

    protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    OleDbConnection conn = new OleDbConnection(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source = C:\Users\Abrahamq\Documents\Database1.accdb;");
                    conn.Open();
                    OleDbCommand command = new OleDbCommand("select * from boekt", conn);
                    OleDbDataReader oleDbDataReader = command.ExecuteReader();
                    this.DataList1.DataSource = oleDbDataReader;
                    this.DataList1.DataBind();
                    oleDbDataReader.Close();
                    conn.Close();
                }
            }
        
        protected string Handle(object ImageUrl)// the person who helped me said my images’ addressess have too many hashes:
            {
                string url = Convert.ToString(ImageUrl);
                return url.Trim('#');
            }
    

    and the aspx side:

            <div>
                <asp:DataList ID="DataList1" runat="server">
                    <ItemTemplate>
                        ID:<asp:Label ID="Label1" runat="server" Text='<%# Eval("ID") %>'></asp:Label>
                        <asp:Image ID="Image2" runat="server" ImageUrl='<%# Handle(Eval("ImageUrl")) %>' Width="50px" Height="50px"/>
                    </ItemTemplate>
                </asp:DataList>
            </div>
    

    I used this exact code, but when I tried it, I didn't get the same results- all I got, was the icon of a broken picture.

    According to the "Locals" tab in C# (when I'm debugging), I can see that the images have been converted to a byte-sequence.

    Can someone please help me?  I don't have enough experience in this and I'm becoming rather discouraged as nothing I tried is working...

    If need be, I'm willing to use OLE's link feature

    Riddlesinmymind

    Tuesday, November 12, 2019 5:49 PM

Answers

  • User665608656 posted

    Hi riddlesinmymind,

    According to your description, I suggest you update your vs version, starting from 2013 there is community version of vs , and vs 2008 is too old to get a installation image so not able to test against 2008 version.

    The main point is 2008 is using .net Framework 3.5 in webform while later version uses 4.5 for webform.

    Your issue may be related to .net Framework version , so I suggest you update your vs version to test those code.

    Best Regards,

    YongQing.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, November 20, 2019 1:36 AM

All replies

  • Tuesday, November 12, 2019 10:22 PM
  • User665608656 posted

    Hi riddlesinmymind,

    According to the "Locals" tab in C# (when I'm debugging), I can see that the images have been converted to a byte-sequence.

    According to your description, do you mean that the content you bind to the imageurl property at this time is of type byte?

    If so, you can convert the binary bytes in the Handle method to the imageurl that can be displayed:

        protected string Handle(object ImageUrl)// the person who helped me said my images’ addressess have too many hashes:
            {
                 string imageurl = string.Empty;
                using (MemoryStream ms = new MemoryStream(ImageUrl as byte[]))
                {
                    imageurl = "data:image/png;base64," + Convert.ToBase64String(ms.ToArray());
                }
    
                return imageurl;
            }

    Here is the result:

    Best Regards,

    YongQing.

    Wednesday, November 13, 2019 5:23 AM
  • User-2116945077 posted

    Hi, YongQing

    Sorry for bothering you, but I have for you:  When you said 

    ..."data:image/png;base64,"...


    in the coding, were you referring to the images in your access database ("image/png")?  Because the images that were embedded in my database says "Package" in the ImageUrl column.  I've tried using your exact code and then changed the "image/png" to "Package/jpg", but neither worked...I still got a broken picture icon.  Both the pictures have a .jpg format.  Do I need to change them?

    I've tried adding a snapshot of my Access Table so that you can see what I'm referring to, but for some reason, I can't upload any pictures/snapshots ...

    Also, what is the purpose of the "base64"

    So close, yet so far...

    Riddlesinmymind

    Wednesday, November 13, 2019 8:25 AM
  • User665608656 posted

    Hi riddlesinmymind,

    Have you tried using the code I gave you? You don't need to change its contents, because this is a fixed way of writing, I can use the jpg files to display.

    If you want to change to jpg, you can change like this :

    "data:image/jpg;base64,"

    This way of writing is to convert the data of type byte[] into the url of image, so that it can successfully display.

    You can use breakpoints for debugging. If you can confirm that the parameter ImageUrl passed in the Handle method is of type byte[], then you can use the method I provided to convert it and display it successfully.

    You can also refer to this link : Display Binary Image from database in ASP.Net GridView control using C# and VB.Net

    Best Regads,

    YongQing.

    Wednesday, November 13, 2019 9:41 AM
  • User-2116945077 posted

    YongQing, it seems that I have to bother you yet again...

    To answer your earlier question, yes, I used you exact code, and only after I was unsuccessful, did I tinker the code a bit...

    Below is all the code that was used for this project, but yet again, I got the broken image icon.

    The code behind:

    protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    OleDbConnection conn = new OleDbConnection(@"Provider = Microsoft.ACE.OLEDB.12.0; Data Source =C:\Users\Anja\Documents\Database3.accdb");
                    conn.Open();
                    OleDbCommand command = new OleDbCommand("select * from boekt", conn);
                    OleDbDataReader oleDbDataReader = command.ExecuteReader();
                    this.DataList1.DataSource = oleDbDataReader;
                    this.DataList1.DataBind();
                    oleDbDataReader.Close();
                    conn.Close();
                }
            }
    
            protected string Handle(object ImageUrl)
            {
                string imageurl = string.Empty;
                using (MemoryStream ms = new MemoryStream(ImageUrl as byte[]))
                {
                   imageurl = "data:image/jpg;base64," + Convert.ToBase64String(ms.ToArray());
              
                }
    
                return imageurl;
            }
    

    and the asp.net side:

    <body>
        <form id="form1" runat="server">
        <div>
                <div>
                <asp:DataList ID="DataList1" runat="server">
                    <ItemTemplate>
                        ID:<asp:Label ID="Label1" runat="server" Text='<%# Eval("ID") %>'></asp:Label>
                        <asp:Image ID="Image2" runat="server" ImageUrl='<%# Handle(Eval("ImageUrl")) %>' Width="50px" Height="50px"/>
                    </ItemTemplate>
                </asp:DataList>
            </div>
    
        </div>
        </form>
    </body>

    I inserted the breakpoint as you suggested, and saw that, during the "using" phrase, the 'ImageUrl' object successfully became the byte[] and later on a base64string, giving the 'imageurl' string the value of:  " imageurl "data:image/jpg;base64,FRwyAAIAAAAWAAgAFAAqAP////9QYWNrYWdlciBTaGVsbCBPYmplY3QAUGFja2FnZQABBQ...."

    As i saw the above value, I wondered whether highlighted part in the above line could be the problem?

     Or could it be that some of my references are wrong or missing?  I'm currently using:

    using System;
    using System.Collections;
    using System.Linq;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Xml.Linq;
    using System.Data.OleDb;
    using System.IO;
    using System.Configuration;
    using System.Data;

    Could you please once again help me?  It leaves me completely flabbergasted to see that the example you've given me worked, and yet when I try it, nothing happens.

    Riddlesinmymind

    Wednesday, November 13, 2019 12:55 PM
  • User665608656 posted

    Hi riddlesinmymind,

    According to your description, there is no problem in code confirmation. I need to check the content of the image field stored in your database.

    How do you store image information in your database?

    I hope you can provide us with your screenshots or details for reference.

    Best Regards,

    YongQing.

    Thursday, November 14, 2019 3:12 AM
  • User-2116945077 posted

    Hi YongQing 

    I will try my best to answer your questions:

    How do you store image information in your database?

    1. When I first created the table, in Design View I added 2 columns;  
      • one was named Id, which has an Autonumber datatype (and is also my Primary Key)
      • and the second one was name ImageUrl, which is an OLE Object datatype
    2. In DataSheet View, I would right-click on the ImageUrl cell  
      •  and select "Insert object..."
      • then, I would select the "Select From File" radio button
      • click on the "Browse" button and select the photo/image/.jpg file I want and click "OK"  
      • Then, without checking either of the checkboxes, I would click OK again
    3.  Once I've done this, the cell I chose would display the word "Package".  When i double-click on it, the image/picture would open.

    I hope you can provide us with your screenshots or details for reference.

    I'm having trouble uploading pictures to forums.asp.net.  Is there any other way that I can send it to you?

    Riddlesinmymind

    Thursday, November 14, 2019 9:35 AM
  • User665608656 posted

    Hi riddlesinmymind,

    Based on your description of the table structure in your access database, I used the same method to reproduce your issue.

    To obtain the data of OLE object datatype of picture type from access database, we need to convert it to Image(System.Drawing.Image) type first, then convert Image to byte[] type, and finally execute the conversion of imageurl.

    For more detailed code, you can refer to the following.

              protected string Handle(object ImageUrl) 
            {
                
                byte[] data = GetOriginal(ImageUrl as byte[]);
                MemoryStream stream = new MemoryStream();
                stream.Write(data, 0, data.Length);
                System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
    
                byte[] imgdata = imageToByteArray(img);
                string imageurl = string.Empty;
                using (MemoryStream ms = new MemoryStream(imgdata))
                {
                    imageurl = "data:image/jpg;base64," + Convert.ToBase64String(ms.ToArray());
                }
                return imageurl;
            }
    private byte[] GetOriginal(byte[] dbbytes) { const string BITMAP_ID_BLOCK = "BM"; const string JPG_ID_BLOCK = "\u00FF\u00D8\u00FF"; const string PNG_ID_BLOCK = "\u0089PNG\r\n\u001a\n"; const string GIF_ID_BLOCK = "GIF8"; const string TIFF_ID_BLOCK = "II*\u0000"; byte[] imgbytes; Encoding e7 = Encoding.UTF7; String strtemp = e7.GetString(dbbytes); String strfirsttemp = strtemp.Substring(0, 300); int iPos = -1; if (strfirsttemp.IndexOf(BITMAP_ID_BLOCK) != -1) iPos = strfirsttemp.IndexOf(BITMAP_ID_BLOCK); else if (strfirsttemp.IndexOf(JPG_ID_BLOCK) != -1) iPos = strfirsttemp.IndexOf(JPG_ID_BLOCK); else if (strfirsttemp.IndexOf(PNG_ID_BLOCK) != -1) iPos = strfirsttemp.IndexOf(PNG_ID_BLOCK); else if (strfirsttemp.IndexOf(GIF_ID_BLOCK) != -1) iPos = strfirsttemp.IndexOf(GIF_ID_BLOCK); else if (strfirsttemp.IndexOf(TIFF_ID_BLOCK) != -1) iPos = strfirsttemp.IndexOf(TIFF_ID_BLOCK); else throw new Exception("Unable to determine header size for the OLE Object"); if (iPos == -1) throw new Exception("Unable to determine header size for the OLE Object"); MemoryStream stream = new MemoryStream(); stream.Write(dbbytes, iPos, dbbytes.Length - iPos); imgbytes = stream.ToArray(); stream.Close(); stream.Dispose(); return imgbytes; } public byte[] imageToByteArray(System.Drawing.Image imageIn) { MemoryStream ms = new MemoryStream(); imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg); return ms.ToArray(); }

    You can also refer to this link : Read OLE Object type image field in C#.net

    Best Regards,

    YongQing.

    Friday, November 15, 2019 5:34 AM
  • User-2116945077 posted

    Hi, YongQing

    Sorry it took me so long to come back to you- I had a few urgent issues that I had to attend to…

    Unfortunately, it seems that I once again have to be the bearer of bad news…It still doesn’t work completely... 

    After I copied your code into the project, I tested it with the .jpg images that were embedded in my database.  When I debugged it, however, an Argument Exception was thrown at “System.Drawing.Image img = System.Drawing.Image.FromStream(stream);in the Handle method, claiming “System.ArgumentException: Parameter is not valid

    Thinking that the jpg file may be the cause of the problem, I deleted the records with .jpg objects and added new record with a png object (I added it in the same manner I described before).  It, however threw an ArgumentNullException at “String strtemp = e7.GetString(dbbytes);” in the “GetOriginal” method,  claiming “System.ArgumentNullException: Array cannot be null. Parameter name: bytes”  

    Deciding to test the other formats, I tested the .bmp, .gif, and .tiff files.  Both the .bmp and the .gif had the same error as the j.pg file. 

    I have a little good news though, the .tiff file WORKED!!!!

    I was beginning to wonder whether a setting on my pc could be the reason for all my troubles  (as in why the other formats don’t work)?  Or could it be the fact that I’m using Visual Studio 2008 alongside Microsoft Office 2010?

    Hoping to hear from you again

    Riddlesinmymind

    Monday, November 18, 2019 8:27 AM
  • User665608656 posted

    Hi riddlesinmymind,

    According to your description, I suggest you update your vs version, starting from 2013 there is community version of vs , and vs 2008 is too old to get a installation image so not able to test against 2008 version.

    The main point is 2008 is using .net Framework 3.5 in webform while later version uses 4.5 for webform.

    Your issue may be related to .net Framework version , so I suggest you update your vs version to test those code.

    Best Regards,

    YongQing.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, November 20, 2019 1:36 AM
  • User-2116945077 posted

    Hi, YongQing

    I have good news... It works!  I tried it on VS 2012( a program that was previously installed but rarely used because of the UI), which also makes use of the .NET Framework 4.5 and it returns all the different formats successfully!laughing

    I have another (and hopefully last) question for you though:

    Sometimes, a book has different covers (during reprinting etc.), but others only have one cover, no matter how many times it has been reprinted.  I've added another column to the database  (OLE Object) and named it "Image2" and added the images to it as explained before.  In the aspx.net page, I've also added another image holder to my Datalist.  Now, my question is: If the cell in the second column is empty after retrieving the data, how can I hide the Datalist's second image tag when debugging and have it continue to the next record without having an exception thrown because the cell is empty?

    The once again blank-slated

    Riddlesinmymind

    Thursday, November 21, 2019 11:46 AM
  • User665608656 posted

    Hi riddlesinmymind,

    I have good news... It works!  I tried it on VS 2012( a program that was previously installed but rarely used because of the UI), which also makes use of the .NET Framework 4.5 and it returns all the different formats successfully!laughing

    I'm glad to have solved your issue. Please mark the reply that is helpful to you as the answer.

    Sometimes, a book has different covers (during reprinting etc.), but others only have one cover, no matter how many times it has been reprinted.  I've added another column to the database  (OLE Object) and named it "Image2" and added the images to it as explained before.  In the aspx.net page, I've also added another image holder to my Datalist.  Now, my question is: If the cell in the second column is empty after retrieving the data, how can I hide the Datalist's second image tag when debugging and have it continue to the next record without having an exception thrown because the cell is empty?

    Since the thread has been replied for a long time, and the question does not match the title of your thread, in order to help users with other similar questions find the answers they want easily, I suggest you reopen a new thread to ask questions, and we will reply to you as soon as possible.

    Best Regards,

    YongQing.

    Monday, November 25, 2019 1:27 AM