PDA

View Full Version : Please help -- how to resize Access OLE database image?


jinlynn
09-14-2004, 05:15 AM
A little background: I have images stored in an Access database as OLE objects. I want to be able to reduce the image size so as to reduce load time when displaying these images in a webpage. I have two asp scripts, one which displays the binary image and one which reduces image size of regular image files. But I don't know how I can combine the two to reduce the size of the embedded image.

Here is script 1 (display database image):
<%
'Step 1: Read in the vin from the querystring
Dim ivinID
ivinID = Request.QueryString("vinnum")
'Step 2: grab the picture from the database
'Dimension variables
Dim adoCon 'Holds the Database Connection Object
Dim rs 'Holds the recordset for the records in the database
Dim strSQL 'Holds the SQL query to query the database
'Create an ADO connection object
Set adoCon = Server.CreateObject("ADODB.Connection")
'Set an active connection to the Connection object using a DSN-less connection
adoCon.Open "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" & Server.MapPath("database/carshowroom.mdb")
'Create an ADO recordset object
Set rs = Server.CreateObject("ADODB.Recordset")
'Initialise the strSQL variable with an SQL statement to query the database
strSQL = "SELECT PHOTO1 FROM tblVEHICLES WHERE VIN LIKE " & "'" & ivinID & "'"
'Open the recordset with the SQL query
rs.Open strSQL, adoCon
'Step 3: Set the ContentType to image/jpeg
Response.Clear
Response.ContentType = "image/jpg"
'Step 4: Use Response.BinaryWrite to output the image
Response.BinaryWrite rs("photo1")
'Clean up...
rs.Close
adoCon.Close
Set rs = NothingadoCon.Close
Set adoConn = Nothing
%>

Here is script 2 (resizes images):
<script language="VB" runat="server">
Sub Page_Load(Sender As Object, E As EventArgs)

Dim orginalimg, thumb As System.Drawing.Image
Dim FileName As String
Dim inp As New IntPtr()
Dim width, height As Integer
Dim rootpath As String
rootpath = Server.MapPath("/") ' Get Root Application Folder
FileName = rootpath & Request.QueryString("FileName") ' Root Folder + FileName
Try
orginalimg = orginalimg.FromFile(FileName) ' Fetch User Filename
Catch
orginalimg = orginalimg.FromFile(rootpath & "error.gif") ' Fetch error.gif
End Try
' Get width using QueryString.
If Request.QueryString("width") = Nothing Then
width = orginalimg.Width ' Use Orginal Width.
ElseIf Request.QueryString("width") = 0 Then ' Assign default width of 100.
width = 100
Else
width = Request.QueryString("width") ' Use User Specified width.
End If
' Get height using QueryString.
If Request.QueryString("height") = Nothing Then
height = orginalimg.Height ' Use Orginal Height.
ElseIf Request.QueryString("height") = 0 Then ' Assign default height of 100.
height = 100
Else
height = Request.QueryString("height") ' Use User Specified height.
End If
thumb = orginalimg.GetThumbnailImage(width, height, Nothing, inp)
' Sending Response JPEG type to the browser.
Response.ContentType = "image/jpeg"
thumb.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)
' Disposing the objects.
orginalimg.Dispose()
thumb.Dispose()
End Sub
</script>

Here is what I am using to display my database photo : <img src=getphoto1.asp?vinnum=$VIN->value">

Is there a way I can use the second script when displaying the photo? For example, I tried using the above call as the filename for the second script, but that doesn't work (<img src=thumbphoto.aspx?filename=getphoto1.asp?vinnum= $VIN->value">).

Thank you for any advice!

jinlynn
09-15-2004, 11:08 PM
I really need some help with this one. Has anyone done this before?

Roy Sinclair
09-15-2004, 11:37 PM
Actually the second page is a .NET page, not an ASP page but you should be able to alter that second script to read the image from your database instead of an image file easily enough. You'll need to learn enough .NET to learn how to read a database (lots of tutorials on how to do that) and replace the following code with your new database reading code and of course the code to copy the image from the recordset retrieved into the "originalimg" object. Once that's done the rest of the code will work fine.


rootpath = Server.MapPath("/") ' Get Root Application Folder
FileName = rootpath & Request.QueryString("FileName") ' Root Folder + FileName
Try
orginalimg = orginalimg.FromFile(FileName) ' Fetch User Filename
Catch
orginalimg = orginalimg.FromFile(rootpath & "error.gif") ' Fetch error.gif
End Try


Your call to the modified second page should be (in the generated html):

<img src="thumbphoto.aspx?filename=getphoto1.asp?filename=nameofimage&width=newwidth&height=newheight">

(obviously you'd also replace nameofimage, newwidth and newheight with actual values too).

jinlynn
09-21-2004, 09:22 AM
B]Mr. Sinclair,

Thank you for responding. I'm trying to do what you recommended, but can't seem to get it working. Below is the code I came up with, but it's not working...do you have any suggestions on what I'm doing wrong? I've tried so many variations. I'm not too sure I'm inserting the ole object into the fullsizeIMG correctly. I really appreciate your advice! [/B]

<%@Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.Data.OleDb" %>
<script language="VB" runat="server">
Sub Page_Load(sender as Object, e as EventArgs)

dim dbconn
dbconn=New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;data source=" & server.mappath("carshowroom.mdb"))
dbconn.Open()
Dim ivinID
Dim sql
Dim dbcomm
Dim dbread
Dim thumb
ivinID = Request.QueryString("vinnum")
sql="SELECT PHOTO1 FROM tblVEHICLES WHERE VIN LIKE " & "'" & ivinID & "'"
dbcomm=New OleDbCommand(sql,dbconn)
dbread=dbcomm.ExecuteReader()
tblVEHICLES.DataSource=dbread
tblVEHICLES.DataBind()

<asp:Repeater id="tblVEHICLES" runat="server">
Dim fullSizeImg as System.Drawing.Image
Dim thumb as System.Drawing.Image
fullSizeImg = System.Drawing.Image.FromFile(#Container.DataItem("PHOTO1"))

' Get width using QueryString.
If Request.QueryString("width") = Nothing Then
width = orginalimg.Width ' Use Orginal Width.
ElseIf Request.QueryString("width") = 0 Then ' Assign default width of 100.
width = 100
Else
width = Request.QueryString("width") ' Use User Specified width.
End If

' Get height using QueryString.
If Request.QueryString("height") = Nothing Then
height = orginalimg.Height ' Use Orginal Height.
ElseIf Request.QueryString("height") = 0 Then ' Assign default height of 100.
height = 100
Else
height = Request.QueryString("height") ' Use User Specified height.
End If

thumb = fullSizeImg.GetThumbnailImage(width, height, Nothing, inp)


Response.ContentType = "image/jpeg"
thumb.Save(Response.OutputStream, ImageFormat.jpeg)

dbread.Close()
dbconn.Close()
end sub
</script>
</asp:Repeater>

Roy Sinclair
09-21-2004, 05:08 PM
My .NET skills are not at all up to much of a challenge yet since I'm mainly working on ASP and VB6 code right now but I don't understand why you added the <asp:Repeater id="tblVEHICLES" runat="server"> and </asp:Repeater> to that page, especially in that fashion since it starts inside a <script> bloack and ends outside that block which definitely makes it not correct.

Are you getting any error messages when you try to run the page?

jinlynn
09-21-2004, 10:48 PM
I'm not familiar with NET at all (I'm sure I don't have to tell you that :) ). I don't think I'm reading the photo into the full size image correctly, but I'm not sure how to do it and this was the only way I'd seen it done. Here is the error message I'm getting:

BC30201: Expression expected.
For this line:
fullSizeImg = System.Drawing.Image.FromFile(#Container.DataItem("PHOTO1"))


I'm just trying to read my PHOTO1 (Access OLE object field) from a table called tblVEHICLES into this variable called fullSizeImg. I think the "FromFile" might be a problem, since it's not really a file I'm giving it, but rather a field in a database. But I don't know how to tell it that. Also, do you know if the "#Container.DataItem" is the correct way to refer to a field in a database? I've seen examples done that way, but I'm clueless as to whether I'm doing it correctly. I appreciate your help

Roy Sinclair
09-21-2004, 11:32 PM
Well that should definitely be FromStream instead of FromFile.

Try looking at this article about getting BLOB objects using OLEDB: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconwritingblobvaluestodatabase.asp

I'm wondering though if there's not something closer to ADODB you could use which would be a lot easier.

Another article that might be a lot friendlier is http://weblogs.asp.net/cazzu/archive/2003/08/27/25568.aspx

jinlynn
09-22-2004, 02:13 AM
I'm not sure this is what I want either. They tell how to display images from Access, which I have gotten to work. I can also resize jpgs that are in a folder and display them. I just can't seem to pull these two things together and it is so frustrating! I've tried so many variations that I've lost track. At one point, I tried using "chunksize", but all that did was display a slice of my photo, depending on what I set chunksize to. I've seen a couple of scripts that could supposedly read particular bits to change the image size, but it seemed to be just for gifs and not jpegs. It just seems like there should be a relatively simple way to alter the binary stream before writing it.

I changed my script a little and have gotten a little further (I think). I'm no longer getting syntax errors -- I've moved up to Security Exceptions. :) This is what I get for the stack trace:

[SecurityException: Request failed.]
ASP.test2_aspx.Page_Load(Object sender, EventArgs e) +0
System.Web.UI.Control.OnLoad(EventArgs e) +67
System.Web.UI.Control.LoadRecursive() +35
System.Web.UI.Page.ProcessRequestMain() +2106
System.Web.UI.Page.ProcessRequest() +218
System.Web.UI.Page.ProcessRequest(HttpContext context) +18
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication+IExecutionStep.Execute() +179
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +87

Does this mean anything to you? I have no idea. I can supposedly set debug to true, but this requires setting the language as C# and everything is written in VB. Once I set it to C#, I start getting syntax errors relating to the C# language. Ugh!

jinlynn
09-22-2004, 03:23 PM
Here is the code that is generating the security exception. Any ideas?

<%@Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.Data.OleDb" %>


<script language="VB" runat="server">
Sub Page_Load(sender as Object, e as EventArgs)
dim dbconn
dbconn=New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;data source=" & server.mappath("carshowroom.mdb"))
dbconn.Open()
Dim ivinID
Dim sql
Dim dbcomm
Dim rs
Dim tblVEHICLES
Dim width
Dim height
Dim inp
ivinID = Request.QueryString("vinnum")
sql="SELECT PHOTO1 FROM tblVEHICLES WHERE VIN LIKE " & "'" & ivinID & "'"

rs.Open (sql, dbconn)

Dim fullSizeImg as System.Drawing.Image
Dim thumb as System.Drawing.Image

Try
fullSizeImg = System.Drawing.Image.FromStream(rs("photo1"))
Catch
fullSizeImg = System.Drawing.Image.FromStream(error.gif)
End Try

If Request.QueryString("width") = Nothing Then
width = fullSizeImg.Width
ElseIf Request.QueryString("width") = 0 Then
width = 320
Else
width = Request.QueryString("width")
End If

If Request.QueryString("height") = Nothing Then
height = fullSizeImg.Height
ElseIf Request.QueryString("height") = 0 Then
height = 240
Else
height = Request.QueryString("height")
End If

Try
thumb = fullSizeImg.GetThumbnailImage(width, height, Nothing, inp)
Catch
thumb = fullSizeImg.GetThumbnailImage(error.gif)
End Try

Response.ContentType = "image/jpeg"
thumb.Save(Response.OutputStream, ImageFormat.jpeg)

rs.Close()
dbconn.Close()
end sub
</script>

Roy Sinclair
09-22-2004, 07:58 PM
You changed too many things to come from the stream:


Try
fullSizeImg = System.Drawing.Image.FromStream(rs("photo1"))
Catch
fullSizeImg = System.Drawing.Image.FromFile("error.gif")
End Try


After all, if there's a problem loading the image, then the error.gif file is going to come from a local file and not the database.


Likewise I think you should probably change the output portion to be like this:


Response.ContentType = "image/jpeg"
Try
thumb = fullSizeImg.GetThumbnailImage(width, height, Nothing, inp)
thumb.Save(Response.OutputStream, ImageFormat.jpeg)
Catch
fullSizeImg.Save(Response.OutputStream, ImageFormat.jpeg)
End Try


That way if there's an error producing the thumbnail at least the full size image will go out.

jinlynn
09-23-2004, 11:28 PM
I am getting the following error:

Compiler Error Message: BC30311: Value of type 'System.Drawing.Image' cannot be converted to '1-dimensional array of Byte'.

Does anyone know how to convert the System.Drawing.Image to binary so I can display it with BinaryWrite?



Below is my code:



<%@Import Namespace="System.Drawing.Imaging" %>
<%@ Import Namespace="System.Data.OleDb" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Drawing" %>


<script language="VB" runat="server">
Sub Page_Load(sender as Object, e as EventArgs)
dim dbconn
dbconn=New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;data source=" & server.mappath("carshowroom.mdb"))
dbconn.Open()
Dim ivinID
Dim sql
Dim dbcomm
Dim rs
Dim tblVEHICLES
Dim width
Dim height
Dim inp
ivinID = Request.QueryString("vinnum")
sql="SELECT PHOTO1 FROM tblVEHICLES WHERE VIN LIKE " & "'" & ivinID & "'"

rs.Open (sql, dbconn)

Dim fullSizeImg as System.Drawing.Image
Dim thumb as System.Drawing.Image

Try
fullSizeImg = System.Drawing.Image.FromStream(rs("photo1"))
Catch
fullSizeImg = System.Drawing.Image.FromFile("error.gif")
End Try

If Request.QueryString("width") = Nothing Then
width = fullSizeImg.Width
ElseIf Request.QueryString("width") = 0 Then
width = 320
Else
width = Request.QueryString("width")
End If

If Request.QueryString("height") = Nothing Then
height = fullSizeImg.Height
ElseIf Request.QueryString("height") = 0 Then
height = 240
Else
height = Request.QueryString("height")
End If

Response.ContentType = "image/jpeg"

thumb = fullSizeImg.GetThumbnailImage(width, height, Nothing, inp)



Response.BinaryWrite(thumb)


rs.Close()
dbconn.Close()
end sub
</script>






I really need to get this working soon -- all help is appreciated!

Roy Sinclair
09-24-2004, 07:33 PM
I don't understand why you replaced this line:

thumb.Save(Response.OutputStream, ImageFormat.jpeg)

which should work with this line:

Response.BinaryWrite(thumb)

which obviously doesn't work.

jinlynn
09-24-2004, 11:44 PM
I was told by someone that it was causing the security exception because it was writing the file to a directory without write permission. I just want to display the resized database photo in the browser window -- not write it to a file. What is the right way to do this? What do you think could be causing the security exception?

Roy Sinclair
09-27-2004, 07:38 PM
If it was writing to a file, then yes but that statement isn't writing to a file or any directory, it's writing to the Response.OutputStream which is a file.

Response.OutputStream is the data which is written to the client browser and that particular statement is the right way to get your newly created thumbnail to that client browser.