• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

cfimage inside cfdocument problem

New Here ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

Very strange, but repeatable issue I've run into.  I'm using the barbecue Java barcode generator library to generate code128 compliant barcodes which are then handed to cfimage writeToBrowser to finally end up with printable packing/mailing labels.  When rendered to screen, everything works perfectly, but as soon as I wrap it in a cfdocument tag, so that we can generate as a pdf for printing on a label printer, I'm ending up with the wrong image on the wrong label in a few cases.  It's always the same records that end up reusing an image from an earlier record (and always the same earlier record).  I can check in the ColdFusion8\tmpCache\CFFileServlet\_cf_image folder and see that all the correct images were created by the cfimage tag, but for whatever reason, some of the images don't make it into the pdf, but are replaced by a different barcode from an earlier record.  I can't see any commonality between the two records and if I intentionally remove the earlier record from the query, the proper barcode shows up.

So, any ideas about where to go from here?  Anybody know anything about how cfdocument pulls in images and if there is any kind of caching or prechecking of the images before rendering.  I actually checked to make sure the two files didn't have the same MD5 sum to see if there was something happening there where CF thinks it's the same image.  They were not the same.

I've tried this on two CF 8.01 boxes with the same result.  Always the same records, same images, same problem, even if I limit the query to only the two problem records.  I'm totally stumped.  Anybody?

Views

10.2K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

Can you post your code?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

Not sure it's helpful, but here's the code, at least the relevant parts.  As I said, I've confirmed that this is all doing what it's supposed to and if I take off the cfdocument, it renders to the screen perfectly every time.

<cfdocument format="PDF" pagewidth="4" pageheight="6.0" pagetype="CUSTOM" margintop="0.17" marginbottom="0.05" marginleft="0.17" marginright="0.17">

<cfset labelCounter = 1 />

<cfoutput query="qryGetShippingLabelData" group="Lab_Code">

  <!--- Do some stuff --->

  <cfoutput group="shipGroup">

    <cfloop from=1 to=#numLabels# index="i">

      <cfset bcText = "" />

      <cfif labelCounter NEQ 1><cfdocumentitem type="pagebreak" /></cfif>

      #labelHead#

      <cfoutput>

        <cfset bcText = bcText & numberFormat(study_id,"00000") & iif(singleSampleBox,1,numSamples) />

      </cfoutput>

                              <cfset bcText = numberFormat(Lab_ID,"00000") & bcText />

                              <p><cfimage action="writeToBrowser" source="#getCode128(bcText)#" /></p>

      #labelFoot#

      <cfset labelCounter = labelCounter + 1 />

    </cfloop>

  </cfoutput>

</cfoutput>

</cfdocument>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

I notice there is lot of looping and grouping going on. Any chance it is related? If you output the "bcText" at each step (inside the pdf) is the value correct? Also, for grins you might output the image URL and confirm whether it is repeating, or the "bcText" is repeating.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

Well, we're on the same page there.  I've done all that you've mentioned and it's always correct (keep in mind, outputing to screen is always working, it's just inside cfdocument that I see this problem and it's always the same records).  The grouping and looping is defintely working as expected and urls to images are the correct urls, even in the pdf, but the image is not what the url is pointing to.  I've pretty well convinced myself that it has to be something about how cfdocument gets images.

As one more piece of data to add, I just tried adding a random integer at the beginning of the bcText, which obviously then generates a different barcode image and it worked correctly, even in the pdf.  So it's something about the particular image files that get created.  I'm thinking only an Adobe CF engineer with knowledge of the inner workings of cfdocument is going to be able to help me.  Anyone know who that might be?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

jeff.c wrote:

Not sure it's helpful, but here's the code, at least the relevant parts.  As I said, I've confirmed that this is all doing what it's supposed to and if I take off the cfdocument, it renders to the screen perfectly every time.

<cfdocument format="PDF" pagewidth="4" pageheight="6.0" pagetype="CUSTOM" margintop="0.17" marginbottom="0.05" marginleft="0.17" marginright="0.17">

<cfset labelCounter = 1 />

<cfoutput query="qryGetShippingLabelData" group="Lab_Code">

  <!--- Do some stuff --->

  <cfoutput group="shipGroup">

    <cfloop from=1 to=#numLabels# index="i">

      <cfset bcText = "" />

      <cfif labelCounter NEQ 1><cfdocumentitem type="pagebreak" /></cfif>

      #labelHead#

      <cfoutput>

        <cfset bcText = bcText & numberFormat(study_id,"00000") & iif(singleSampleBox,1,numSamples) />

      </cfoutput>

                              <cfset bcText = numberFormat(Lab_ID,"00000") & bcText />

                              <p><cfimage action="writeToBrowser" source="#getCode128(bcText)#" /></p>

      #labelFoot#

      <cfset labelCounter = labelCounter + 1 />

    </cfloop>

  </cfoutput>

</cfoutput>

</cfdocument>

The code needs improving. The PDF may render correctly after that, who knows.

1) You have, at the centre of it all, code that is within 3 loops. It will help to scope the variables, such as qryGetShippingLabelData.x and shipGroup.y.

2) The cfouput tag in the following stretch is unnecessarily in the way:

      <cfoutput>

        <cfset bcText = bcText & numberFormat(study_id,"00000") & iif(singleSampleBox,1,numSamples) />

      </cfoutput>

Then again, if you drop this cfoutput tag you will get:

<cfset bcText = bcText & numberFormat(study_id,"00000") & iif(singleSampleBox,1,numSamples) />

<cfset bcText = numberFormat(Lab_ID,"00000") & bcText />

That looks like repetition to me. At least, it doesn't appear to me that that was the intention.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

Nope.  All grouping and loops are necessary based on the shape of the data and the required output based on the number of labels required for each row in the source query.  I'm doing something at each stage of the grouping (although I removed some of that because it wasn't really relevant to the question) to build these labels.  I'm quite confident that the grouping and looping is correct and not part of the problem.  In fact, I've built a simple test page that removes all the complexity of my grouping and query and will still produce this problem (although you have to have the barbecue library to test).

<cfset bbq = createObject("java", "net.sourceforge.barbecue.BarcodeFactory") />

<cfset ih = createObject("java", "net.sourceforge.barbecue.BarcodeImageHandler") />

 

<cfscript>

          function getCode128 (data)           {

    barcode = bbq.createCode128(data);

    barcode.setBarWidth( 1 );

    barcode.setBarHeight( 50 );

    barcode.setDrawingText( false );

    barcode.setDrawingQuietSection( false );

    barcode.setResolution( 200 );

 

    newImg = ih.getImage( barcode );

    barcodeImage = ImageNew(newImg);

 

    return barcodeImage;

          }

</cfscript>


<cfset list = "00413001811,00403001811" />

 

<cfdocument format="pdf" pagewidth="4" pageheight="6.0" pagetype="CUSTOM" margintop="0.17" marginbottom="0.05" marginleft="0.17" marginright="0.17">

<html>

          <head>

          </head>

          <body>

                    <cfloop list="#list#" index="i">

                              <p><cfimage action="writetobrowser" source="#getCode128("#i#")#" /></p>

                              <p><cfoutput>#i#</cfoutput></p>

                    </cfloop>

          </body>

</html>

</cfdocument>

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

          function getCode128 (data)           {

               barcode = bbq.createCode128(data);

               barcode.setBarWidth( 1 );


After seeing the function code, first thing I would recommend is VAR scoping all of the function local variables. Then try it again.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

-==cfSearching==- wrote:

          function getCode128 (data)           {

               barcode = bbq.createCode128(data);

               barcode.setBarWidth( 1 );


After seeing the function code, first thing I would recommend is VAR scoping all of the function local variables. Then try it again.

In fact, I would VAR newImg and barcodeImage as well.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

In fact, I would VAR newImg and barcodeImage as well.

Yep, that is why I said all function local variables. I was only trying to highlight the fact that were no VAR scope declarations at the top of the function. (I did not look over the  variable names in detail 🙂

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

-==cfSearching==- wrote:

In fact, I would VAR newImg and barcodeImage as well.

Yep, that is why I said all function local variables. I was only trying to highlight the fact that were no VAR scope declarations at the top of the function. (I did not look over the  variable names in detail 🙂

Nice of you, but you needn't explain. It was an oversight. I was already thinking VAR myself, and so just skimmed 'barcode' and 'VAR'. Sorry.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 04, 2012 Apr 04, 2012

Copy link to clipboard

Copied

It is clear you are dealing with just 2 images in this simpler example. Please just bear with me and explain what problem you reproduce with the 2 images.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

jeff.c wrote:

Nope.  All grouping and loops are necessary based on the shape of the data and the required output based on the number of labels required for each row in the source query.  I'm doing something at each stage of the grouping (although I removed some of that because it wasn't really relevant to the question) to build these labels.  I'm quite confident that the grouping and looping is correct and not part of the problem.  In fact, I've built a simple test page that removes all the complexity of my grouping and query and will still produce this problem (although you have to have the barbecue library to test).

<cfset bbq = createObject("java", "net.sourceforge.barbecue.BarcodeFactory") />

<cfset ih = createObject("java", "net.sourceforge.barbecue.BarcodeImageHandler") />

<cfscript>

          function getCode128 (data)           {

    barcode = bbq.createCode128(data);

    barcode.setBarWidth( 1 );

    barcode.setBarHeight( 50 );

    barcode.setDrawingText( false );

    barcode.setDrawingQuietSection( false );

    barcode.setResolution( 200 );

    newImg = ih.getImage( barcode );

    barcodeImage = ImageNew(newImg);

    return barcodeImage;

          }

</cfscript>


<cfset list = "00413001811,00403001811" />

<cfdocument format="pdf" pagewidth="4" pageheight="6.0" pagetype="CUSTOM" margintop="0.17" marginbottom="0.05" marginleft="0.17" marginright="0.17">

<html>

          <head>

          </head>

          <body>

                    <cfloop list="#list#" index="i">

                              <p><cfimage action="writetobrowser" source="#getCode128("#i#")#" /></p>

                              <p><cfoutput>#i#</cfoutput></p>

                    </cfloop>

          </body>

</html>

</cfdocument>

The question remains why it fails with, but works without, cfdocument. Does cfdocument introduce a new page context? I wonder. If so, then what -==cfSearching==- said about varring the variables would immediately make sense. Unvarred variables belong to the context of the current page.

Another issue may arise from  <cfloop list="#list#" index="i">. You implicitly assume that ColdFusion will process the list elements in the exact order in which they appear in the list. I suspect ColdFusion wont always. It may internally apply some kind of sorting, and begin with the last element in the list.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

@BKBK: I don't want to sidetrack the thread here, but that last statement about assuming the order of processing on a list in the CFLOOP tag is pretty concerning. I've never witnessed any behavior other than processing the list exactly in the order provided, and I have a hard time believing that we've just been lucky for 15 years. That /is/ in fact a key assumption in lots of CFML code. Do you have a basis for that statement, either in the docs or repeatable behavior in code you can share? To have them processed in anything other than the order provided seems so counterintuitive as to render the whole concept of using a list to drive any sort of iteration as basically useless...

--

/ron

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

cf_ron wrote:

@BKBK: I don't want to sidetrack the thread here, but that last statement about assuming the order of processing on a list in the CFLOOP tag is pretty concerning. I've never witnessed any behavior other than processing the list exactly in the order provided, and I have a hard time believing that we've just been lucky for 15 years. That /is/ in fact a key assumption in lots of CFML code. Do you have a basis for that statement, either in the docs or repeatable behavior in code you can share? To have them processed in anything other than the order provided seems so counterintuitive as to render the whole concept of using a list to drive any sort of iteration as basically useless...

No need worrying or running for the hills, Ron. I wrote that piece without due attention. What I omitted says more about what I was thinking.

I was trying to puzzle out why ColdFusion would start looping a list at position 2, or at any position other than 1 for that matter. What I wished I had said follows.

Another issue may arise from  <cfloop list="#list#" index="i">. If the list is indeed as it appears in the code, then there is no issue. However, suppose the list was comprised of the keys of a struct. That is, the list of keys is structKeyList(theStruct), and you've stated the list in the code as a simplified test page. You implicitly assume that ColdFusion will process the list elements in the exact order in which they appear in the list. I suspect ColdFusion wont always. It may internally apply some kind of sorting, and begin with the last element in the list.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

@BKBK: No worries here. If I get the gist of your comment, it was centered around the question of whether the list itself was ordered as expected rather than whether the list was iterated over in order from first to last?

--

/ron

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

jeff.c sent me a copy of his code and image files referenced above, and I have duplicated this behavior on a fully-updated 9.01 box. Same exact behavior, so it is clearly not something unique to 8.01 or something that has been patched in 9.x. I have a CF10 box I will try this on in a bit, as well...

Update: also does not work on CF10 beta -- same behavior.

--

/ron

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

I, too, have tested on CF 10 Beta. I painted a stripe across one of the barcodes for easier recognition.

_cfimg6949878617879408634.PNG                              _cfimg300382366701370250.PNG

(respectively: _cfimg6949878617879408634.png, _cfimg300382366701370250.png)

Then I ran the following code, first, without cfdocument, then with cfdocument.

<!---<cfdocument format="pdf" pagewidth="4" pageheight="6.0" pagetype="CUSTOM" margintop="0.17" marginbottom="0.05" marginleft="0.17" marginright="0.17">--->

<html>

<head></head>

<body>

  <div><img id="_cfimg6949878617879408634" src="_cfimg6949878617879408634.png" /></div>

  <p>00413001811</p>

<div><img id="_cfimg300382366701370250" src="_cfimg300382366701370250.png" /></div>

  <p>00403001811</p>

</body>

</html>

<!---</cfdocument>--->

In both cases, the result was:

result.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

@BKBK - Your test would validate my hypothesis that cfdocument is doing something to look at the images and determine if they have already been loaded and, if so, reuse the already loaded image.  Whatever that comparison is based on is treating these two images as the same image.  Since you've altered the original image, I'm not surprised that it now works correctly, but if you go back to the original images, unaltered, I'm quite confident you'll see the same behavior.  For what it's worth, I compared the MD5 sum of the two images and they do not match.

@cfSearching - What you're seeing would also validate what I'm thinking.  Once you include the text, you've fundamentally altered the signature of the image and cfdocument isn't mistaking them anymore.  I'm not comfortable just including the barcode text though and hoping that it solves the problem.  In my mind, it's still possible and likely that the underlying engine could still be confused in comparing images when I'm generating hundreds of these barcodes in a pop, and if it only happens very occasionally, then it's almost more problematic since I'd have to validate every single label to make sure it's right.  In any case, you're right.  I think I need to try and get some help from Adobe.  I'm filing a bug right now.

UPDATE: Bug filed in adobe Bugbase - https://bugbase.adobe.com/index.cfm?event=bug&id=3158895

Message was edited by: jeff.c

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

I'm not comfortable just including the barcode text though and hoping

that it

solves the problem.  In my mind, it's still possible and likely

that the underlying

engine could still be confused in comparing images

We are on the same page there. I would not rely on it either. It just helps illustrate the issue a bit more clearly.

 

-Leigh

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 06, 2012 Apr 06, 2012

Copy link to clipboard

Copied

Leigh, you might want to change the text rendered red in your code to quoted strings.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 06, 2012 Apr 06, 2012

Copy link to clipboard

Copied

Leigh, you might want to change the text rendered red in your code to quoted strings.

Yes, you are right but that is courtesy of this lovely forum software ;-). After it mangled the original (with quotes) three times, I finally gave up. I am not sure it lets you edit posts after other responses are added. I will check the web interface later.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 06, 2012 Apr 06, 2012

Copy link to clipboard

Copied

I think I was finally able to reproduce the behavior on 9.01. But it only happens when setDrawingText(..) is false.

I further tested the same code on CF 10 Beta. Irrespective of whether I used barcode.setDrawingText(false) or barcode.setDrawingText(true), I did reproduce the issue. Also, when I changed the order of the numbers from ["00413001811","00403001811"] to ["00403001811","00413001811"], the barcode image changed, but the issue persisted.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 06, 2012 Apr 06, 2012

Copy link to clipboard

Copied

jeff.c wrote:

@BKBK - Your test would validate my hypothesis that cfdocument is doing something to look at the images and determine if they have already been loaded and, if so, reuse the already loaded image.  Whatever that comparison is based on is treating these two images as the same image.  Since you've altered the original image, I'm not surprised that it now works correctly, but if you go back to the original images, unaltered, I'm quite confident you'll see the same behavior.  For what it's worth, I compared the MD5 sum of the two images and they do not match.

Your confidence is justified! I reran my above test with the original image. I did reproduce the issue.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 05, 2012 Apr 05, 2012

Copy link to clipboard

Copied

(Update:  Grr... I just love this forum software.)

I think I was finally able to reproduce the behavior on 9.01. But it only happens when setDrawingText(..) is false.

<cfscript>

    /* deliberately refactored to eliminate  var scoping issues as a possible cause */

    function getCode128 ( data, hideText )           {

        var bbq = createObject("java", "net.sourceforge.barbecue.BarcodeFactory");

        var ih = createObject("java", "net.sourceforge.barbecue.BarcodeImageHandler");

        var barcode = bbq.createCode128( arguments.data );

        barcode.setBarWidth( 1 );

        barcode.setBarHeight( 50 );

        barcode.setDrawingQuietSection( false );

        barcode.setResolution( 200 );

        if ( structKeyExists(arguments, "hideText") and arguments.hideText ) {

            barcode.setDrawingText( false );

        }

        return ImageNew(ih.getImage( barcode ));

    }

</cfscript>

<cfset numbers = ["00413001811","00403001811","00413001811","00403001811"] />

<cfdocument format="pdf">

    <cfloop from="1" to="#arrayLen(numbers)#" index="i">

        <cfset imgText  = numbers />

        <cfset hideText = i lte 2 />

        <cfoutput>

           [#i#] #imgText# <cfimage action="writetobrowser" source="#getCode128(imgText, hideText)#" /><br />

        </cfoutput>

    </cfloop>

</cfdocument>

jeff.c wrote:

maybe at least an acknowledgement from an Adobe rep that there may be an issue here?

Well these are user-to-user forums. If you want to speak with an adobe representative, you need to use official channels. (While I have seen an occaisional comment here and there, it is rare. So it is extremely unlikely you would get a response from an Adobe employee here).

Message was edited by: -==cfSearching==-

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation