Link to home
Start Free TrialLog in
Avatar of Coast Line
Coast LineFlag for Canada

asked on

A Basic Image Function related to Coldfusion

My question is Pretty Simple.

I generate text on Image.. i can do it [so far so good]

Here is the function for that

<cfset objImage = ImageNew("",200,50,"argb")>
<cfset objTextProperties = {Size = "#url.size#",Font = "#url.mailfont#",Style = "bold",LineHeight = "35",TextAlign = "left"}>
<!--- Draw the text area. --->
<cfset ImageSetAntialiasing(ObjImage)>
<cfset ImageSetDrawingColor(ObjImage,"#url.color#")>
<cfset imageDrawText(objImage,"#url.s#",5,25,0,objTextProperties)>
<!--- Write to browser. --->
<cfimage action="writetobrowser" source="#objImage#">

No i am passing another image which i have stored on my system.. i want to merge the generrated image with the image i have but how:

 i tried something like this but i am doing is wrong!

the code above is same

only after the write to browser tag

<cfset firstimage = ImageRead("s_logo/gmailcom.gif")>
<cfdump var="#firstimage.source#">
<cfset combineImages = "#objImage##firstImage#">
<cfimage action="writetobrowser" source="#combineimages#">

I know this is wrog but how can i do this
Avatar of Zvonko
Zvonko
Flag of North Macedonia image

Simply use instead of ImageNew() the ImageRead() function:

<cfset objImage = ImageRead("s_logo/gmailcom.gif")>
<cfset objTextProperties = {Size = "#url.size#",Font = "#url.mailfont#",Style = "bold",LineHeight = "35",TextAlign = "left"}>
<!--- Draw the text area. --->
<cfset ImageSetAntialiasing(ObjImage)>
<cfset ImageSetDrawingColor(ObjImage,"#url.color#")>
<cfset imageDrawText(objImage,"#url.s#",5,25,0,objTextProperties)>
<!--- Write to browser. --->
<cfimage action="writetobrowser" source="#objImage#">

Avatar of Coast Line

ASKER

Ok It is working but the image i am writing is overlapping it

See the attached image

 i tried like this:

<cfset objImage = ImageRead("s_logo/gmailcom.gif")>
<cfset objTextProperties = {Size = "#url.size#",Font = "#url.mailfont#",Style = "bold",LineHeight = "35",TextAlign = "left"}>
<!--- Draw the text area. --->
<cfset ImageSetAntialiasing(ObjImage)>
<cfset ImageSetDrawingColor(ObjImage,"#url.color#")>
<cfset imageDrawText(objImage,"#url.s#",5,25,objTextProperties)>
<!--- Write to browser. --->
<cfimage action="writetobrowser" source="#objImage#">
-cfimg-2301283172830683627.PNG
i am just trying like my generated image should be like this:

randhawaz81 [I generated it]

@domain.com [The image i already have]

the result i am trying to do:

randhawaz81@domain.com

Hope u understand what i am trying here
Any uodate experts! the answer you provided just overlap the image, i want to make a one image combining two images!

So any more advanced experts can actually do this

Regards
SOLUTION
Avatar of Zvonko
Zvonko
Flag of North Macedonia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Only for completeness, the struct can be written like this:

<cfset objTextProperties = {Size=url.size, Font=url.mailfont, Style="bold", LineHeight=22, TextAlign="right"}>

Awesomwe! Thanks for the Beautiful Update! I really want what you did here! llast tweek! what if we want to apply the shadow to the text we are generating

My One question is whyy you used:

<cfset leftImage = ImageNew("",url.size*Len(url.s)/1.55,22,"argb")>

the 1.55 value

if the font is smaller or bigger it will cover additional space or can generate the extra space

any workaround for this
Ok Here is also what i am trying to do! joining the two images but getting an error:

<cfset image1 = ImageRead("temp/left1.png")>
    <cfset image2 = ImageRead("temp/right1.png")>
      <cfset Width1 = ImageGetWidth(Image1)>
      <cfset ImageCrop(image1,0,0,Width1+ImageGetWidth(Image2),ImageGetHeight(image1))>
      <cfset TempFile = ExpandPath("sssss") & "\" & CreateUUID() & ".png">
      <cfset ImageWrite(#TempFile#)>

Error!

Unable to cast an object of type java.lang.String to Image.

"if the font is smaller or bigger it will cover additional space or can generate the extra space"
For that in the calculation you have three factors:
Font size
String Length
Font correction factor from size to pixel.

The last factor can of course be different for different font names but the would be to far to make a table of values. Better try to find you best mean value for the third factor. My guess was 1.55

What you are trying to do with crop is absolute to high for me. Therefore I assume that you are trying to complicate things to hide that you do not get the basics.

Instead doing the crop thing better make one image from the logo that is right part and empty space on the left part of the same image.
Load that image with the empty space on the left and do the positioning to the right depending on font size, string length and so on.
That calculation is complicated enough and you need not to deal with crop thing.


Yeah Actual Trouble is coming up where i need to find a way how to merge images! that is really a trouble!

Your suggestion of not using crop method but then how can i do! i read yuor last comments but really did not understood the point you are trying to clarifty to me!
OK, what I say is this: instead merging two images you define on bride image where right part is the logo that you would like to merge to the right side. But you do that merging not again and again by ColdFusion image functions but only once in PaintBrush image editor tool. Merge two images in PaintBrush. Create one empty left side image and one logo right side in one image. Then you do load that one image with empty space on the left side and do the text write functions to the empty space. The only problem that you have then are the text positions x and y coordinates. And you have to calculate the x and y based on your font size and text length so that you can shift the text with the x coordinate to the right next to the logo image.

You see?

Ok Let's Do in step by Step Procedure!

1. What we do is create a Blank Image by measuring the dimensions of bother the left and right image and paste the images on them. [Is this viable Solution, or not!]

2. I want this to be with Cf image functions not using any Additional third party software

Leaving font formatting asside we can first do how to merge the two files i see the same that was one in cfimageInfo custom Coldfusion tag by cherylSoft

If that can be done no matter coldfusion has much more inbuild functionalities!

3. If preferred we are also use undocumented features of Coldfusion like java methods that can help us build it
Any Update on this!
1) download imageUtils cfc from http://imageutils.riaforge.org and upzip it to a folder within your site root.
this cfc has very nifty functions to work with text and images - exactly what you need.

2) attached is the code to create the image you want using cf's built-in functions and imageutils methods:

Azadi
<!--- setup url parameters --->
<cfparam name="url.s" default="randhawaz81">
<cfparam name="url.color" default="red">
<cfparam name="url.mailfont" default="Arial">
<cfparam name="url.fontsize" default="12">
<!--- 
create image using ImageUtils.cfc's and cf's built-in functions.
final image will have text on the left and domain image on the right, both aligned horizontally to center of image.
 --->

<cfscript>
/* init ImageUtils component */
objImageUtils = createobject('component', 'imageutils.imageutils'); // change path to imageUtils.cfc as required

/* read existing image */
domainImg = imageread('s_logo/gmailcom.png'); // change as required

/* set up text and its properties */
text = trim(url.s);
textProps = {'Font'=url.mailfont, 'Size'=url.fontsize, 'Style'='bold', 'RightPadding'=ceiling(url.fontsize/6)}; //RightPadding value is space between text and domain image; arbitrary, but based on my tests fonsize/6 seems to work best
textDim = objImageUtils.getTextDimensions(text, textProps); // get text's dimensions (width and height) using getTextDimensions() method of ImageUtils cfc

/* setup properties of final image */
imgProps = {};
imgProps.height = max(domainImg.height, textDim.height); // set height to the larger one of text height or domain image height
imgProps.width = domainImg.width+textDim.width+textProps.RightPadding;
imgProps.bgcolor = 'white'; // change to the bg color of domain image or whhichever

/* create final image by pasting domain image and writing text into it */
finalImg = imagenew('', imgProps.width, imgProps.height, 'rgb', imgProps.bgcolor);
imagesetantialiasing(finalImg, 'on');
imagepaste(finalImg, domainImg, imgProps.width-domainImg.width+textProps.RightPadding, round(imgProps.height/2-domainImg.height/2)); // paste domain image
imagesetdrawingcolor(finalImg, url.color); // set text color
textPosY = objImageUtils.getCenteredTextPosition(finalImg, text, textProps.Font, 'bold', textProps.Size).y; // get Y coord where to write text in final image using getCenteredTextPosiotion() method of imageUtils cfc
imagedrawtext(finalImg, text, 0, textPosY, textProps); // draw text on final image
</cfscript>
<!--- output final image to browser --->
<cfimage action="writetobrowser" source="#finalImg#">

Open in new window

Awesome @azadi Great JOb, One issue is there when i generate the last .COM is being cut from end the end little

please check the attached image

According to my tests:

'RightPadding'=ceiling(url.fontsize/4)} worked with 4 well as 6 was overtaking the generated name over tthe image


-cfimg4963093553660945811.PNG
what i i wanna provide shadow to this also with differnt color

>> One issue is there when i generate the last .COM is being cut from end the end little

ah, my mistake.
in the imagepaste() line, change
+textProps.RightPadding
to
-textProps.RightPadding
so that the whole line is:
imagepaste(finalImg, domainImg, imgProps.width-domainImg.width-textProps.RightPadding, round(imgProps.height/2-domainImg.height/2));

>> what i i wanna provide shadow to this also with differnt color

can you explain this more? want exactly do you want to apply shadow to? the text in the image? the whole image?
keep in mind that the whole final image has a solid white background...

can you create an image in fireworks/photoshop/whatever how you would like the final image to look and attach it here?

Azadi

doh... i need more coffee!

there should not be any +/-textProps.RightPadding in the imagepaste() line at all. just this:

magepaste(finalImg, domainImg, imgProps.width-domainImg.width, round(imgProps.height/2-domainImg.height/2));

Azadi
Thanks Dude it is now ok:

i have two options either i create a shadow of the generated image or

second option is i should create a outline of the name with the different color

like the attached one..

the one like the cfsearching has done here:

http://cfsearching.blogspot.com/2009/10/coldfusion-draw-text-outline-on-image.html

like the background is transparrent and name has been outlined with a color
attached is edited code.

you can pass url.style to the page and set it to 'outline' or 'shadow' and text will be drawn accordingly.
if no url.style variable is passed, plain text is drawn (no shadow and no outline)

if you want different shadow color, pass it in url.shadowcolor variable

IMPORTANT: now all colors you pass in the url must be defined as HEX color codes, NOT as color name. i.e. instead of passing color="red" you must pass color="#cc0000"

Azadi
<!--- setup url parameters --->
<cfparam name="url.s" default="randhawaz81">
<cfparam name="url.color" default="##990000">
<cfparam name="url.mailfont" default="Arial">
<cfparam name="url.fontsize" default="46">
<cfparam name="url.style" default="">
<cfparam name="url.shadowcolor" default="##666666">
<!--- 
create image using ImageUtils.cfc's and cf's built-in functions.
final image will have text on the left and domain image on the right, both aligned horizontally to center of image.
 --->

<cfscript>
/* init ImageUtils component */
objImageUtils = createobject('component', 'imageutils.imageutils'); // change path to imageUtils.cfc as required

/* read existing image */
domainImg = imageread('s_logo/gmailcom.png'); // change as required

/* set up text and its properties */
text = trim(url.s);
rightPadding = ceiling(url.fontsize/4);
if (url.style eq 'outline') rightPadding = ceiling(url.fontsize/3);
else if (url.style eq 'shadow') rightPadding = rightPadding+2;
textProps = {'Font'=url.mailfont, 'Size'=url.fontsize, 'Style'='bold', 'RightPadding'=rightPadding}; //RightPadding value is space between text and domain image; arbitrary, but based on my tests fonsize/6 seems to work best
textDim = objImageUtils.getTextDimensions(text, textProps); // get text's dimensions (width and height) using getTextDimensions() method of ImageUtils cfc

/* setup properties of final image */
imgProps = {};
imgProps.height = max(domainImg.height, textDim.height); // set height to the larger one of text height or domain image height
imgProps.width = domainImg.width+textDim.width+textProps.RightPadding;
imgProps.bgcolor = 'white'; // change to the bg color of domain image or whhichever

/* create final image by pasting domain image and writing text into it */
finalImg = imagenew('', imgProps.width, imgProps.height, 'argb');
textPosY = objImageUtils.getCenteredTextPosition(finalImg, text, textProps.Font, 'bold', textProps.Size).y; // get Y coord where to write text in final image using getCenteredTextPosiotion() method of imageUtils cfc

/* draw text */
// plain text (url.style = 'plain' or not defined)
if (url.style neq 'outline' AND url.style neq 'shadow') { 
	imagesetantialiasing(finalImg, 'on');
	imagesetdrawingcolor(finalImg, url.color); // set text color
	imagedrawtext(finalImg, text, 0, textPosY, textProps); // draw text on final image
}
// outline text (url.style = 'outline' NOTE: only good for very large font size!
if (url.style eq 'outline') { 
	graphics = ImageGetBufferedImage(finalImg).createGraphics();
	RenderingHints = createObject("java", "java.awt.RenderingHints");
	graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
	graphics.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
	Font = createObject("java", "java.awt.Font");
	textFont = Font.init("Arial", Font.BOLD, textprops.Size);
	textColor = createObject("java", "java.awt.Color").decode(url.color);
	fontContext = graphics.getFontRenderContext();  
	layout = createObject("java", "java.awt.font.TextLayout").init(text, textFont, fontContext);
	transform = createObject("java", "java.awt.geom.AffineTransform").init();  
	transform.setToTranslation( 0, textPosY );
	shape = layout.getOutline(transform);
	graphics.setColor(textColor);
	graphics.draw(shape);
	graphics.dispose();
}
// draw text with shadow (url.style = 'shadow' and url.shadowcolor is set)
if (url.style eq 'shadow') { 
	imagesetantialiasing(finalImg, 'on');
	imagesetdrawingcolor(finalImg, url.shadowcolor);
	imagedrawtext(finalImg, text, 2, textPosY+2, textProps);
	imagesetdrawingcolor(finalImg, url.color);
	imagedrawtext(finalImg, text, 0, textPosY, textProps);
}
imagepaste(finalImg, domainImg, imgProps.width-domainImg.width, round(imgProps.height/2-domainImg.height/2)); // paste domain image
</cfscript>
<!--- output final image to browser --->
<cfimage action="writetobrowser" source="#finalImg#">
<cfoutput>
<div style="background-color: ##f5f5f5; width:#imgProps.width#; height=#imgProps.height#;">
	<cfimage source="#finalImg#" action="writeToBrowser">
</div>
</cfoutput>

Open in new window

Thanks!

this line troubles me a lot

rightPadding = ceiling(url.fontsize/4);

if the name is just one character, its OK

if the name gets larger and larger, its cuts its last words see the attached image


-cfimg4963093553660945811.PNG
sorry LAST A is being cut
ok here is what i changed and it works now properly showing all the text in full image:

rightPadding = ceiling(url.fontsize);
if (url.style eq 'outline') rightPadding = ceiling(url.fontsize);
else if (url.style eq 'shadow') rightPadding = rightPadding+12;

can u explain me why i removed the division factor beacuse this causes confusion as you used them to align properly and now when i used it i have too change them..

now as i changed the the lines..

the longer the email address i enter, the better it gets created, the shorter the email address is:

 the more space is generated..

why so

overall its perfect
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks a Ton! This is really Great Dude! Thanks To zvonko also who helped me a lot in the start of this and leter he left i do not why but thanks to all experts here who helped in solving this issue!
You are welcome.
And sorry but I was busy in last days and you got so great support from Azadi so I did not want to bring in unnecessary confusion :-)