(none) imager-devel
/ help / lists / applications / search /
 

Scaling fonts not working as expected

From: Peter Wood (
20020@xyz.molar.is)
Date: Tue 19 Mar 2013 - 13:21:41 GMT

  • Next message: Tony Cook: "Re: Scaling fonts not working as expected"

    Hello,

    I'm working on a script that tries to determine whether a string rendered in a given font will exceed the width of the image, and, if so, scale the font down so that it fits inside the image. It's not working as I would expect, however. The test script appears below so that you can try to replicate the results yourself. What ends up happening is that the string in the scaled-down font appears to take up roughly the same width as the original font, and start at roughly the same point. That means that as it gets smaller, the string moves further off the left hand side of the image until it's completely invisible.

    Any suggestions as to how to address this?

    Thanks,

    Peter

    script below:

    #!/usr/local/bin/perl

    # imager_scaling_test
    #
    # This is a script designed to test whether we can
    # dynamically scale a font down so that it fits within
    # the width of an image. This is designed to be run
    # under mod_perl and viewed in a web browser.
    #
    # Test examples:
    #
    # This works fine:
    # imager_scaling_test?string=TEST
    #
    # This produces output that goes partially outside of the box
    # imager_scaling_test?string=TESTTTTTTTTTTTTT
    #
    # This produces output that is completely outside of the box
    # imager_scaling_test?string=TESTTTTTTTTTTTTTTTTTTTTTTTTTTT

    use strict;
    use Apache;
    use CGI;
    use Imager;
    use Imager::Font;

    my $r = Apache->request;
    my $q = CGI->new();

    # Some variables to control our test
    my $string = $q->param( 'string' ) || 'TEST';
    my $image_width = 400;
    my $image_height = 400;
    my $font_size = 70;
    my $font_file = your_font.ttf';

    # Create a basic imager object to work in
    my $image = Imager->new( xsize => $image_width, ysize => $image_height );

    # Create a box on the image
    $image->box(
        xmin => 0,
        xmin => 0,
        xmax => $image_width - 1,
        ymax => $image_height - 1,
        filled => 1,
        color => 'blue'
    );

    # Set up the font
    my $font = Imager::Font->new( file => $font_file, size => $font_size );

    # Find out how wide our test string would be in this font
    my $bbox1 = $font->bounding_box( string => $string );
    my $initial_width = $bbox1->display_width();
    $r->log_error( "Initial width:$initial_width" );

    # Find out whether the test string is wider than the image
    if ( $initial_width > $image_width ) {

        # Find the difference between the string width and the image width
        my $difference = $initial_width - $image_width;

        # Find the percentage the image width is of the initial width
        my $percentage = $image_width / $initial_width;

        # Set up a scaling matrix to scale the font
        my $scaling_matrix = [ $percentage, 0, 0, 0, $percentage, 0 ];
        $font->transform( matrix => $scaling_matrix );
        my $bbox2 = $font->bounding_box( string => $string );
        my $scaled_width = $bbox2->display_width();
        $r->log_error( "Scaled width:$scaled_width" );
    }

    # Place the string on the image
    $image->align_string(
        valign => 'center',
        halign => 'center',
        font => $font,
        x => $image->getwidth / 2,
        y => $image->getheight / 2,
        text => $string,
    );

    # Print the image out to the browser.
    my $output;
    $image->write( type => 'jpeg', data => \$output );
    binmode STDOUT;
    $r->content_type( "image/jpeg" );
    $r->send_http_header;
    $r->print( $output );

    Attachments:



  •