1

I have been working on a script that will allow users to asynchronously upload images.

the script contains several segments of code and while most of it works like a charm i've been experiencing issue while trying to convert coldfusion image object to blob, pass it to another object (cfc component method), insert values to DB using stored procedure and finaly output blob images to see the result.

here is the testing code for particular segment i am having issues with, the final one will be a bit more complex:

<cfimage source="#CFFILE.ServerDirectory#\#CFFILE.ServerFile#" 
        name="Image" overwrite="no">
        <cfif ImageGetWidth(Image) lt 1024>
        <cfset ArrayAppend(set.Errors,"you can not add image that's less than 1024px wide")>
        <cfelse>

        <!---now resize image scale to fit (709px wide)--->
        <cfset ImageSetAntialiasing(Image,"on")>
        <cfset ImageScaleToFit(Image,709,"","highestPerformance")>

            <!---now crop image if height is more than 350px--->  
            <cfif ImageGetHeight(Image) gt 350>
            <cfset yPosition  = (ImageGetHeight(Image) - 350) / 2>
            <cfset ImageCrop(Image, 0, yPosition, ImageGetWidth(Image), 350)>
            </cfif>

        </cfif>
   </cfif>

   <cfif ArrayLen (set.Errors) is 0>
   <cfset testAddImage = testImg.AddImage(finalImage=#ImageGetBlob(Image)#)>
   </cfif>

need to admit that did not use much image functions with CF, hence I have to learn a few tricks. anyway, as i can see this testing code apparently works considering that all values are neatly added to the DB every time the form has been submited and no CF nor client side errors are thrown. on the other hand, although I read a lot about outputting blob I am pretty much confused what's the best approach to achieve this with CF 10. that said, should I use cfcontent, binaryEncode, to string or something else to do it right.

I've also tried to set a binary object,

<cffile action = "readBinary" file = "#CFFILE.ServerDirectory#\#CFFILE.ServerFile#" variable = "Image">

as well as set ImageNew , however as I could see everything was the same. is there a difference between a binary and image object!?

EDIT

  1. Am I correctly passing binary object into the database?
  2. what is the difference between a binary and image object!? as i can see these two look the same when returned with JSON and displayed on client (alert). 3.the most important question is how to output blob images?

that said, i will output first X images (say first page) server side and allow users to load more with jquery AJAX call.

for server side I would have something like this:

<cfset sqlQueries = createObject ("component","cfc.sqlQueries")>
<cfset loadImages = sqlQueries.LoadImagesDB(orderBy="Date")>
<cfoutput query="loadImages">
#image# - how to display blob images here
</cfoutput>

what's the best way to get blob image, cfcontent, binaryEncode, to string...should i use writeToBrowser? I really do not have much experience with image functions in CF and blob, so I would really appreciate if you could help me sort it out :)

EDIT

@Leigh "A good way to learn more is to try them all." while I was waiting someone to respond here, I've read and tested all of the aforementioned CF features and came to a conclusion (you also pointed out) that action=writeToBrowser is the way to go as it performs great, more specifically as it can compress images in the process.

"obvious disadvantage to database storage is it can dramatically increase the size of your database" thank you for bringing this up, that is my biggest concern. I would personally store images in folders but my partner (who is DB expert by the way) has been insisting to use blobs, though he has been urging me to compress images as much as I can while maintaining performance.

that said, the code above compress (while resizing) say 900KB image to 200-300 kb which is still way to big if you ask me and would eventually lead to what you pointed out (slower db response time, slow backup etc) even though we have only two columns ID and image (longblob).

that said, the code above compress (while resizing) say 900KB image to 200-300 kb which is still way to big if you ask me and would eventually lead to what you pointed out (slower db response time, slow backup etc) even though we have only two columns ID and image (longblob).

user2595617
  • 219
  • 3
  • 13
  • 2
    (Edit) What is your actual question here? :) How to store the images, retrieve them, display them, ...? (BTW, if your question relates to a database query, you need to tell us which DBMS (and version) you are using.) – Leigh Sep 14 '13 at 21:34
  • check out EDIT :) almost forgot, I have been using MySQL 5.5 – user2595617 Sep 15 '13 at 06:23

1 Answers1

3

1 . Am I correctly passing binary object into the database?

To answer that question we need to see the actual code for the function that adds the image to the database, and know the data type are you are using for the target column (blob, longblob, ..).

Also, if you are not familiar with storing blobs in a database, you should definitely weigh the pros and cons of database versus file system storage. Both have disadvantages, but one obvious disadvantage to database storage is it can dramatically increase the size of your database, especially if you are storing large images.

2 . What is the difference between a binary and image object?

A CF image object is just a wrapper around the binary image data. The wrapper contains the binary data, plus some extra (CF-specific) methods that are used by the CF server when you invoke any of the built in image tags/functions.

3 . How to output blob images? What's the best way to get blob image, cfcontent, binaryEncode, to string... Should I use writeToBrowser?

Best is relative. With the exception of toString(), any of those methods can be used to display an image. It all depends on how and where you want to display them. In this case, using action=writeToBrowser would probably be the simplest. The source can be either a CF image object or the raw binary of an image.

  • action=writeToBrowser - Writes the binary data to a temporary file on disk and generates an <img> tag for you. If you use the tag, and do a view source, you will see it generates something like this:

     <img src="/CFFileServlet/_cf_image/_cfimgxxxx.PNG" alt="" />
    
  • cfcontent Generally used to return a single file, such as for a file download. It can be used in conjunction with inline images as well, but would involve a separate script, which returns the binary image with <cfcontent>. The separate script is then used as the source of an inline image tag <img src="somePageWithCFContent.cfm?param=...." />

  • binaryEncode(binary, encoding) Can be used to embed an image as base64. (Better suited to smaller images, and browser support varies).

A good way to learn more is to try them all. Review the documentation on each function, run some test code, then check the "view source" of the generated html. That will give you a good sense of how each of them work.

Community
  • 1
  • 1
Leigh
  • 28,765
  • 10
  • 55
  • 103
  • first thanks for your detailed response, i really appreciate it :) – user2595617 Sep 15 '13 at 18:09
  • now, is there a way to additionally compress images before inserting them to DB without significantly slowing the application down. – user2595617 Sep 15 '13 at 18:11
  • I've tested all available CF image algorithms for resizing and can say that there is not much difference in final image size. so how can I further compress images before proceeding with DB insert. – user2595617 Sep 15 '13 at 18:27
  • *my partner has been insisting to use blobs* What are their reasons for preferring blob over the file system? (Personally, I always store images on disk.) I am more familiar w/SQL Server, but know MySQL it offers a compress function as well compression options. However, it is an additional step, so it will obviously add *some* time (just like pulling blobs out of the db across the network). If your partner is a dba, you should discuss with him the best way to minimize the impact. – Leigh Sep 15 '13 at 18:30
  • ok I'll check that with him. on the other hand, is there a way to compress images just a bit with CF.I would be satisfied with additional 20-30% – user2595617 Sep 15 '13 at 18:42
  • As far as built in options, only what you are doing now ie tweaking the quality http://www.bennadel.com/blog/1638-Ask-Ben-CFImage-And-Dynamic-Image-Compression-With-File-Size-Limits.htm – Leigh Sep 15 '13 at 18:56
  • I've read Ben's blog post but he writes the image to the disk! I tried to use some of the code in my scenario but was not able adjust the quality and insert in DB (my curent code is posted above). I decided to use image functions instead of cfimage so I do not have to write image to disk!? as I mentioned several times before I am new to this and would really like to learn more! – user2595617 Sep 15 '13 at 19:05
  • can I write it to temp for the second time or I need to write it to disk and than delete it? – user2595617 Sep 15 '13 at 19:25
  • Well since you are uploading the file w/cffile, you are already using the file system (and I assume deleting that file at the end). So I do not see why you could use the same technique he is using. Another option is using [VFS (virtual file system)](http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSe9cbe5cf462523a0-70e2363b121825b20e7-8000.html). BTW, you should probably open a separate thread about image compression. Since that is a different topic than in your title, so someone looking for an answer might not find it if they did not read through all of the comments. – Leigh Sep 15 '13 at 19:42