Imagemagick and web fonts - text

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

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.

How to get a pdf embedded fonts using PDFBOX0.8.0

My code:
FileInputStream pdfFile = new FileInputStream("C:/work/pdf2tiff/test.PDF");
PDDocument pdDocument = PDDocument.load(pdfFile, true);
PDDocumentCatalog catalog = pdDocument.getDocumentCatalog();
List pages = catalog.getAllPages();
if (pages != null && pages.size() > 0) {
for (int i = 0; i < pages.size(); i++) {
PDPage page = (PDPage) pages.get(i);
Map fonts = page.getResources().getFonts();
System.out.println("fonts=" + fonts);
I got output:
fonts={F0=org.apache.pdfbox.pdmodel.font.PDType1Font#8aaed5,
F4=org.apache.pdfbox.pdmodel.font.PDType0Font#dc4414,
F2=org.apache.pdfbox.pdmodel.font.PDType0Font#f98ce0,
F6=org.apache.pdfbox.pdmodel.font.PDTrueTypeFont#18fcdce}
Why the fonts map's key is F0/F1/F2/F6? What these mean?
Should I iterate all pdf pages get all fonts?
Thanks for your answer.
It seems like the pdf you loaded has multiple fonts loaded. I couldn't figure out any way to retrieve fonts from a document (which I think should be available for us to retrieve since we load fonts to a particular document).
I'm guessing when you load a font into the document it uses "F0", "F1", etc as keys to map to PDFont type. When you print fonts object, it's printing the memory location of the object.
To get all the embedded fonts, you can create a new HashMap() object, then iterate over all the pages and add each font to your HashMap(). Then you can iterate over the keys, get the PDFont font object and, use font.getSubType() to get some sort of description of the font.
Hope this helps. Good luck!

ImageMagick/Perl sorting images by Pixel width/height

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.

trying to extract formatted images from indesign into a separate folder

I'm looking for a way to extract images from an ID file in a 'formatted' / cropped form.
i.e: a. I have placed numerous, hi-res (tiff, psd) images into an InDesign CS5 file
b. The image boxes that they have been placed into, are smaller than the actual image (pretty intense cropping occurred) c. I am trying to collect these images in their new stage (cropped to the image box) and export them as jpg at 72dpi.
Are there any plug-ins out there that would automatically collect "formatted" images from ID for me? Or is there some other way?
If you're familiar with Indesign Scripting, this can very easily be done via a script. I use Javascript but this can be done with VBSript or AppleScript as well. Here is a basic example of a script that will open a document, and export a rectangle (your image box) as a JPG. Basically, you can just loop through the pictures in your document and export each one to a location/filename you choose (see the myFile variable below). There are several "jpegExportPreferences" you can pick from to determine how your output JPG will be (i.e. DPI).
test();
function test(){
var myDoc = app.open('c:/user/desktop/testDocument.indd');
var myGroups = myDoc.groups;
//for each group...
for (var i = 0;i < myGroups.length; i++){
// for each rectangle in the group...
for(var r = 0; r< myGroups[i].rectangles.length; r++){
var myRect = myGroups[i].rectangles[r];
app.jpegExportPreferences.exportResolution = 300;
app.jpegExportPreferences.jpegQuality = JPEGOptionsQuality.MAXIMUM;
//give it a unique name
var myFile = new File('c:/users/desktop/newJPG' + myRect.id + '.jpg');
myRect.exportFile(ExportFormat.JPG, myFile);
}
}
}
For a list of the other optional JPG Export preferences, see this link:
http://indesignscriptingreference.com/cs2/javascript-cs2/jpegexportpreference.htm
Hope this helps!

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