ImageMagick/Perl sorting images by Pixel width/height - linux

Hi I am having trouble finding any info on how to list images by pixel width or height with Image Magick. what I want to do is filter out images that are less than a specified size of pixel width or height. This is done through a perl script and any help is appreciated.

Based on some code I use for other stuff:
use strict;
use warnings;
use Image::Magick;
use Win32::Autoglob;
my $max_cols = 640;
my $max_rows = 480;
IMAGE:
for my $image_name (#ARGV) {
my $image = Image::Magick->new;
my $result = $image->Read($image_name);
die "Failed to read $image_name - $result" if $result;
my ($cols, $rows) = $image->Get('columns', 'rows');
next IMAGE if $cols > $max_cols;
next IMAGE if $rows > $max_rows;
# your processing here...
}

Use identify utility from ImageMagick to obtain width and height.

Install the PerlMagick perl module from
http://www.imagemagick.org/script/perl-magick.php
Use code similar to the Example Script
examples from that web page to read each image.
Query the number of rows and columns in each image using
$image->Get('rows')
and
$image->Get('columns') and skip images that are too small.

Related

Poor quality jpeg resize on GD library use. Wrong steps?

So I have the following script to resize an incoming jpg and save it to the server in a new size. The created jpg file has terrible quality, even when I am making the quality 90 on the imagejpeg. I am wondering if I am messing it up earlier in my efforts.
// Get new sizes
list($width, $height) = getimagesize($filename);
$percentW=298/$width;
$newwidth = $width * $percentW;
$newheight = $height * $percentW;
// Creating a blank canvas to put the new file. Is this an extra step?
$thumb = imagecreatetruecolor($newwidth, $newheight);
$source = imagecreatefromjpeg($filename);
// Now I create the resized photo with the needed width and height on the blank canvas with the source file resized
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Output to server, define 90% quality. My guess is the quality is destroyed before now.
imagejpeg($thumb,"../../uploads/buckets/" . $_POST["bucket"] . "/" .$fileNameBucket,90);
imagedestroy($thumb);
Am I messing up the quality before I even output the file to the server? Should I use resample instead of resize? I am stuck with using the GD library so ImageMagick is not an option. Thanks.

view RGBA image

Can someone tell me how can I view an RGBA image? I just want a tool that I can display an RGBA image with!
I have written a code, which outputs only RGBA format. I just want to verify if my code worked, and just want to find a simple tool to view this image.
I wasn't able to come across a software to be able to display a RGBA image.
Thanks in advance.
RGBA files only contain raw channel data. The binary data will not have enough information to display an image (ie. width,height,depth, &tc).
If you know the image dimensions of each .rgba file, you should be able to work with the data. Here's an example of viewing raw date in javascript.
var fr = new FileReader(),
myWidth = 200,
myHeight = 200;
fr.onload = function(frEvent) {
var canvasElement = document.getElementById("myCanvas"),
ctx = canvasElement.getContext("2d"),
blob = ctx.createImageData(myWidth,myHeight),
index = 0;
while(index < frEvent.target.result.length)
blob.data[index] = frEvent.target.result.charCodeAt(index++);
ctx.putImageData(blob,0,0);
}
Imagemagick will be able to display raw RGBA data. Assuming that each color sample is 8 bits.
display -size 200x200 -depth 8 mySimpleData.rgba

PerlTk canvas + pixel manipulation

I'm having some problems understanding how the image types in PerlTk work.
I basically want a way to create an "empty" image (for example fully white) and then manipulate the pixel data. I need to able to change a pixel to black or white.
I've tried a few approaches but non of them seem to work. Documentation seems to be pretty scarce and very old. This is closest I've got.
#args name, width, height, data
my $bitmap = $mw->DefineBitmap('cells', 1, 1, pack("b1", "1"));
#args x-pos, y-pos, bitmap-name
$canvas->createBitmap(0, 0, -bitmap => 'cells');
Another idea I had was to use a Photo element but I couldn't find any documentation on how to create one with the "-data" option.
Any help is appreciated.
Use the put() method if you have to set single pixels. Here's a complete example:
use Tk;
my $mw = tkinit;
my $p = $mw->Photo(-width => 100, height => 100);
my $l = $mw->Label(-image => $p, -border => 0)->pack;
for (0..99) {
$p->put("#000000", -to => $_,$_);
$p->put("#000000", -to => 100-$_,$_);
}
MainLoop;

Imagemagick and web fonts

Does anyone know if ImageMagick can be powered by a web font? (Or perhaps feed in via STD IN?) I tried the line below with no luck:
convert -fill black -font http://fonts.googleapis.com/css?family=Diplomata+SC -pointsize 72 label:'Acme Dynamite Company, LLC' logo.png
My goal would be to let users choose a Google Web Font.
If you wget the GWF API, it returns a TTF url:
$ wget -qO- "http://fonts.googleapis.com/css?family=Diplomata+SC" | urlext2
http://themes.googleusercontent.com/static/fonts/diplomatasc/v1/JdVwAwfE1a_pahXjk5qpNonF5uFdDttMLvmWuJdhhgs.ttf
$
Final update: The user barethon wrote a python woff to ttf converter, which works perfectly. (https://github.com/hanikesn/woff2otf/blob/master/woff2otf.py) I'm now able to rip down the font I want from Google, convert it to ttf and use it with imagemagick. Slightly more complicated than I would have liked, but no big deal.
I know this is pretty old at this point, but in the interest of savings others some times, here is some basic PHP to do what you want. It could be optimized to use curl and such, but this should be enough to get people going. It appears that when accessed from a browser it returns a woff and woff2 url, but when accessed from anything else it returns a tff.
$fontUrl = 'http://fonts.googleapis.com/css?family=Anton';
$fontDescription = file_get_contents($fontUrl);
$startStr = 'url(';
$startStrLen = strlen($startStr);
$start = strpos($fontDescription, $startStr) + $startStrLen;
$end = strpos($fontDescription, ')', $start);
$tffUrl = substr($fontDescription, $start, $end - $start);
$tffFile = '/tmp/anton.ttf';
file_put_contents($tffFile, file_get_contents($tffUrl));
$im = new Imagick();
$im->setFont($tffFile);
$im->newPseudoImage(100, 100, "caption:Hello");
$im->setImageFormat('png');
$im->setImageBackgroundColor(new ImagickPixel('transparent'));
header('Content-Type: image/png');
echo $im->__toString();
Thank you to Floss for your approach to this problem. I solved it in a similar way.
The reason I used a random number rather than a static filename like font.ttf is in case other users were calling the function at the same time, it could create an issue.
Query the Google Fonts list
$url = 'https://www.googleapis.com/webfonts/v1/webfonts?key=YOUR KEY HERE';
$responseString = file_get_contents($url);
$fontJSON = json_decode($responseString);
Access the url of the fonts like so:
<select name="font">
<?php foreach ($fontJSON->items as $font): ?>
<option value="<?= $font->files->regular ?>"><?= $font->family ?></option>
<?php endforeach; ?>
</select>
Note that you'd have to do some other trickery to select the variants (like bold or italic) but that's beyond this post.
After passing the form data to the server, use it in the following way.
//create a random number for a unique filename
$random_number = intval( "0" . rand(1,9) . rand(0,9) . rand(0,9) . rand(0,9) . rand(0,9) );
//download the TTF from Google's server
$font_contents = file_get_contents($font);
//Make a local file of a unique name
$font_file = fopen("/tmp/$random_number.ttf", "w");
//Write data from the Google Font file into your local file
fwrite($font_file, $font_contents);
//Close the file
fclose($font_file);
//Set iMagick to use this temporary file
$draw->setFont("/tmp/$random_number.ttf");
//DO YOUR iMagick STUFF HERE
Delete the temporary font file
unlink("tmp/$random_number.ttf"); //remove tmp font

How to display vertical text (90 degree rotated) in all browsers?

How can I display vertical text (90 degree rotated) in all browsers?
(source: sun.com)
The problem is independent from the server side language. If it's not a problem when the vertically rendered text isn't text anymore but an image, choose the solution provided by tharkun. Otherwise, there are ways to do it in the presentation layer.
First, there's (at the moment) an IE-only solution, which is part of the CSS3 standard. You can check it live.
p {
writing-mode: tb-rl;
}
The CSS3 text module also specify some properties for text orientation.
Other guys do it with SVG.
I don't think you can rotate text with PHP/HTML/CSS. But you can create an image with GD containing vertical text.
Example:
header ("Content-type: image/png");
// imagecreate (x width, y width)
$img_handle = #imagecreatetruecolor (15, 220) or die ("Cannot Create image");
// ImageColorAllocate (image, red, green, blue)
$back_color = ImageColorAllocate ($img_handle, 0, 0, 0);
$txt_color = ImageColorAllocate ($img_handle, 255, 255, 255);
ImageStringUp ($img_handle, 2, 1, 215, $_GET['text'], $txt_color);
ImagePng ($img_handle);
ImageDestroy($img_handle);
function verticletext($string)
{
$tlen = strlen($string);
for($i=0;$i<$tlen;$i++)
{
$vtext .= substr($string,$i,1)."<br />";
}
return $vtext;
}
there you go no echo
Text rotation is also possible with other browsers.
CSS:
/*Safari*/
-webkit-transform: rotate(-90deg);
/*Firefox*/
-moz-transform: rotate(-90deg);
/*Opera*/
-o-transform: rotate(-90deg);
/*IE*/
writing-mode: tb-rl;
filter: flipV flipH;
I use the function below if table header rows are too long. It's quite useful because it's easy to use, fast and you don't have to calculate text height & width. Those css-gimmicks just don't work.
#######################################################
# convert text to image and embed it to html
# uses /tmp as a cache to make it faster
# usage: print imagetext("Hello my friend");
# Created by Ville Jungman, GPL-licenced, donated by www.varuste.net
function imagetext($text,$size = 10,$color = array(253,128,46)){
$dir = "/tmp/tekstit";
$filename = "$dir/" . base64_encode($text);
if(!file_exists($filename)){
$font = "/usr/share/fonts/truetype/freefont/FreeSans.ttf";
$box = imagettfbbox($size,90,$font,$text);
$w = -$box[4] - 1;
$h = -$box[3];
$im = imagecreatetruecolor($w,$h);
$white = imagecolorallocate($im,$color[1],$color[2],$color[3]);
$black = imagecolorallocate($im, 0x00, 0x00, 0x00);
imagecolortransparent($im,$white);
imagefilledrectangle($im, 0, 0, $size, 99, $white);
imagettftext($im,$size,90,$size,$h,$black,$font,$text);
#mkdir($dir);
imagepng($im,$filename);
imagedestroy($im);
}
$data = base64_encode(file_get_contents($filename));
return "<img src='data:image/png;base64,$data'>";
}
This thread suggests that you can write text to an image and then rotate the image.
It appears to be possible with IE but not with other browsers so it might be one of those little win for IE6 =)
imagettftext oughta do the trick.
As far as I know it's not possible to get vertical text with CSS, so that means that the rotated text has to be in an image. It's very straightforward to generate with PHP's' libgd interface to output an image file.
Note however that this means using one script to produce the image, and another to produce the surrounding web page. You can't generally (inline data: URI's notwithstanding) have one script produce more than one page component.
Use raphaeljs
It works on IE 6 also
http://raphaeljs.com/text-rotation.html
function verticletext($string)
{
$tlen = strlen($string);
for($i=0;$i<$tlen;$i++)
{
echo substr($string,$i,1)."<br />";
}
}

Resources