crop an image from the centre using coldfusion - image

This is my first bit of programming in quite a while, so I'm basically starting from scratch, and I'm using coldfusion 8.
What I'm trying to do is create a series of uniform thumbnail images (always 68 X 46) from a variety of larger images, some portrait, some landscape. In both cases resizing the image to fill the height or width of the thumbnail and then cropping the excess image equally off either side (top/bottom, left/right). Just as photoshop does by default with canvas resize.
The code below works really well as long as the source images dimensions/ratio is perfect, but I've started to run into cases where the code fails. In this case, when a resized images width ends up being less than 68.
<cfif FileExists(ExpandPath('images/gallery/thumbs/thm_'&imageMed[i].medium.XmlText)) IS false> <!--- If the thumb doesn't exist, create it. --->
<cfif imageDataThumb.width gt imageDataThumb.height >
<!--- Landscape --->
<cfset ImageResize(cfImageThumb,"","46")>
<cfset ImageCrop(cfImageThumb,(cfImageThumb.width-68)/2,0,68,46)> <!--- Crop left/right edges of images --->
<cfimage source="#cfImageThumb#" action="write" destination="images/gallery/thumbs/thm_#imageMed[i].medium.XmlText#" overwrite="yes">
<cfelse>
<!--- Portrait --->
<cfset ImageResize(cfImageThumb,"68","")>
<cfset ImageCrop(cfImageThumb,0,(cfImageThumb.height-23)/2,68,46)>
<!--- Crop top/bottom edges of images --->
<cfimage source="#cfImageThumb#" action="write" destination="images/gallery/thumbs/thm_#imageMed[i].medium.XmlText#" overwrite="yes">
</cfif>
Trying to solve these "edge cases" is turning the code into a mess. Is there a better way to approach this? Something in coldfusion or a cfc?

I know this is old, but you could just use AspectCrop in the imageUtils library from ben nadel. Check riaforge.com. It does exactly what you are looking for. I know, i wrote it. :)

I'd check the proportions of the image first and adjust the short side crop accordingly. I'm using CFScript for conciseness, but this could easily be converted to Coldfusion tags.
<cfscript>
minimumRatio = 68 / 46; // 1.478 (68 pixels / 46 pixels)
width = ImageGetWidth(imageDataThumb);
height = ImageGetHeight(imageDataThumb);
// determine the longside and the aspect
if (width GT height) {
longside = width;
shortside = height;
aspect = "landscape";
} else {
longside = height;
shortside = width;
aspect = "portrait";
}
// determine the aspect ratio
if (longside / shortside GTE minimumRatio) {
// Do normal resize / crop
if (width EQ longside) {
// landscape
} else {
// portrait
}
} else {
// ratio is too small - perform some additional calculations before resize / crop
// in this case, you'll likely need to resize for the opposite side then crop the excess
}
</cfscipt>
<cfimage source="#cfImageThumb#" action="write" destination="images/gallery/thumbs/thm_#imageMed[i].medium.XmlText#" overwrite="yes">
If you don't want to check for ratio, then verify the length and width is enough before resizing using similar logic.

The code needs to not only pay attention to the current ratio, but how you're changing the ratio with the crop.
Also, the height calculation was based on half the desired height, and should have been the full height.
Assuming all else is correct with your code, you should be able to place the code below into your FileExists if block, replacing the current content.
<cfset CurrentWidth = imageDataThumb.width>
<cfset CurrentHeight = imageDataThumb.height>
<cfset CurrentRatio = CurrentWidth / CurrentHeight>
<cfset DesiredRatio = 68 / 46>
<cfif CurrentWidth GTE CurrentHeight>
<!--- Landscape Image --->
<cfif CurrentRatio LT DesiredRatio>
<!--- More Landscape --->
<cfset Keep = "width">
<cfelse>
<!--- Less Landscape --->
<cfset Keep = "height">
</cfif>
<cfelse>
<!--- Portrait Image --->
<cfif CurrentRatio GT DesiredRatio>
<!--- More Portrait --->
<cfset Keep = "height">
<cfelse>
<!--- Less Portrait --->
<cfset Keep = "width">
</cfif>
</cfif>
<cfif Keep EQ "width">
<!--- Crop top/bottom edges of images --->
<cfset ImageResize(cfImageThumb,"68","")>
<cfset ImageCrop(cfImageThumb,0,(cfImageThumb.height-46)/2,68,46)>
<cfelse>
<!--- Crop left/right edges of images --->
<cfset ImageResize(cfImageThumb,"","46")>
<cfset ImageCrop(cfImageThumb,(cfImageThumb.width-68)/2,0,68,46)>
</cfif>
<cfimage source="#cfImageThumb#" action="write" destination="images/gallery/thumbs/thm_#imageMed[i].medium.XmlText#" overwrite="yes">

No. ImageScaleToFit would makes sure the image fits inside the bounds, which in this case leaves white space. I need to completely fill the available space with image.

Related

ColdFusion: ImageScaleToFit

I have an image Slider with different images. Some of the images has the size ratio of 600x400px, others 400x600px.
But the gallery has the width of 570px and height of 350px.
I want to resize the pictures. They should go in the 570x350px size, without distortions.
I tried this:
<cfimage
action = "read"
source = "#getPfad.Wert##getBild.Dateiname#"
name = "bild_gross"
>
<cfset ImageSetAntialiasing(bild_gross)>
<cfset ImageScaleToFit(bild_gross,570,350)>
<cfimage
action="writetobrowser"
source="#bild_gross#"
>
But the image size won't change! The images are cut off.
Edit: The code works, if I try it without the gallery.
<div id="bilder">
<div id="amazingslider-wrapper-1" style="display:block;position:relative;max-width:706px;padding-left:0px; padding-right:146px;margin:0px auto 0px;">
<div id="amazingslider-1" style="display:block;position:relative;margin:0 auto;">
<ul class="amazingslider-slides" style="display:none; ">
<cfloop query="getBild">
<li>
<a href="#getPfad.Wert##getBild.Dateiname#" class="html5lightbox">
<cfimage
action = "read"
source = "#getPfad.Wert##getBild.Dateiname#"
name = "bild_gross"
>
<cfset ImageSetAntialiasing(bild_gross)>
<cfset ImageScaleToFit(bild_gross,570,350)>
<cfimage
action="writetobrowser"
source="#bild_gross#"
>
</a>
</li>
</cfloop>
</ul> ...
Does anyone know, what I can do?
How about using CSS? object-fit enables you to crop an inline image by specifying how it squishes and stretches inside its box. Using cover will enable the image to fill the height and width of its box while maintaining the aspect ratio but auto-crop the image if needed. (I'm not sure whether IE fully supports this yet or not, but there's a hack in the link below.)
<img src="/myimage.jpg" style="object-fit:cover;" width="570" height="350">
More info at https://css-tricks.com/almanac/properties/o/object-fit/
I suggest don't do image processing in your display/view. ImageScaleToFit function will resize the image and will use server resources each time users visit.
Have a separate function to process and resize those images. Then use the <img> tag to display those images. Using the img html tag will give you more options in controlling your display.

Raphaeljs IE8 setViewBox not working

I use RaphaelJS for generate SVG. My SVG is 1024px width and height.
I use setViewBox because the div containing it is more small than 510px width and height.
With IE8 RaphaelJS produces VML but setViewBox is not working, the size of VML produced is 1024px.
How I can make that VML responsive?
paper = Raphael(document.getElementById("SVGDiv"));
paper.canvas.id = 'paper';
paper.setViewBox(0,0,1024,1024);
paper.setViewBox(0,0,1024,1024);
image = paper.image("",0,0, 1024, 1024);
text = paper.text(512, 512, '');
if( isIE() > 8 || isIE() == false){
paper.setSize("100%","100%");
}

How To Crop An Image To a Specific Shape

Okay so in SpriteKit I am trying to make a node that has its own physics body and will collide with the player. The problem is the actual image is not a square. It is like a the L tetris block shape. It is a png so the background of the image is blank, however when the character collides with the image it collides with it before the actual image gets to it, because the blank png is still part of the image. So I was wondering if it is possible to cut out that "blank" part of the image so that the character will only collide with the actual image seen.
Here is the code I have for the node:
-(void)makeblock2 {
SKSpriteNode *block2 = [SKSpriteNode spriteNodeWithImageNamed:#"block2.png"];
block2.position = CGPointMake(150,300);
block2.alpha = 1;
block2.size = CGSizeMake(block2.size.width / 2, block2.size.height / 2);
block2.name = #"block2";//how the node is identified later
block2.zPosition = 100;
block2.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(block2.size.width, block2.size.height)];
block2.physicsBody.categoryBitMask = wallCategory;
[myWorld addChild: block2];
}

CFDocument displays wrong images

I am using ColdFusion 9 to create a PDF containing multiple QR codes.
Images were successfully created before generating the PDF document. The images are different to each other but they have a similar file size and resolution.
Now I generate HTML for each of the previous generated images and put it into a PDF document. The path is correct – I checked it.
<cfset amount="6" />
<cfdocument
format="pdf"
unit="cm"
marginTop="0.5"
marginLeft="0.5"
marginRight="0.5"
marginBottom="0.5"
pageType="A4"
filename="#path##name#.pdf">
<cfoutput>
<cfloop from="1" to="#amount#" index="i">
<cfset filename = "#name#_#i#" />
<img src="file://#path#codes/#filename#.png" style="width: 3.58cm; margin: 0 0.2cm 0.5cm;">
#path#codes/#filename#
</cfloop>
</cfoutput>
</cfdocument>
But there is one problem: Only the first image is displayed properly. Every other image is an identical copy of the first one. So I got 6 identical images in this PDF document.
Let me point out that the paths are right. It is not 6 times the same path.
Some completely different images are displayed properly. I think Coldfusion has some problems with displaying nearly identical (file size, resolution) images.
Is there a way to fix this problem?
Solved the problem.
There is a problem in ColdFusion with CFDocument and PNG bar code images. I converted them to JPG and everything works as expected.
<cfset amount="6" />
<cfdocument
format="pdf"
unit="cm"
pageType="A4"
filename="#path##name#.pdf">
<cfoutput>
<cfloop from="1" to="#amount#" index="i">
<cfset filename = "#name#_#i#" />
<cfimage
action="convert"
destination="#path#codes/#filename#.jpg"
source="#path#codes/#filename#.png" />
<img src="file://#path#codes/#filename#.jpg" style="width: 3.58cm; margin: 0 0.2cm 0.5cm;">
</cfloop>
</cfoutput>
</cfdocument>
Thank you for your help!

How to avoid resized images being blurred in Coldfusion?

I'm resizing and saving some images using Coldfusion8. However, all images, no matter what size are blurred and I don't know how to turn it off.
This is what I'm doing:
<cfimage action="read" source="#variables.basePath#" name="base">
<cfscript>
variables.height = 127;
variables.width = "";
ImageScaleToFit(base, variables.width, variables.height);
variables.offset = ImageGetWidth( base ) - 100;
if ( variables.offset GT 0 )
{
imageCrop( base, variables.offset/2, 0, 100, 127 );
}
variables.filekey = "s_" & img_paths.bilddateiname;
variables.filename = variables.tempDirectory & variables.keyName;
imageWrite( base, variables.filename, ".99" );
</cfscript>
Any idea what I'm doing wrong? The images are blurred no matter if I convert to 800x1110px or the above 100x127. The base picture is sharp, so it must be something I'm doing when resizing.
Thanks for inputs!
EDIT:
original image:
resized image:
Using CF9.0.2
Using your source jpeg, your code, and hardcode the output to be y.jpg:
What's wrong? Isn't this what you expect?

Resources