Re: [RFC] Dynamic image generator handler
Hi, I am a little bit late for this thread, but anyway... I looked at Apache::ImageMagick last night however, and although it seems pretty usefull, it doesn't really address what I want to do with my module. I read your original RFC and as far as I see you can do everything you have requested with Apache::ImageMagick. What are you missing? Beside the fact that your benchmark shows that ImageMagick is slower then GD (but ImageMagick also handle a lot more picture formats then GD, for example I use it to convert TIFF input files to jpeg) What about the idea from Ed, to have one module, where you can drop in different backends? Would this be an idea to extent Apache::ImageMagick, so that it can use other grapical libraries? Gerald - Gerald Richterecos electronic communication services gmbh Internetconnect * Webserver/-design/-datenbanken * Consulting Post: Tulpenstrasse 5 D-55276 Dienheim b. Mainz E-Mail: [EMAIL PROTECTED] Voice:+49 6133 925131 WWW:http://www.ecos.de Fax: +49 6133 925152 -
Re: [RFC] Dynamic image generator handler
On Wed, 8 May 2002, Michael A Nachbaur wrote: With regard to dynamic image creation The most basic uses of this application will to dynamically generate TTF text for titles, buttons, sidebars, etc. The current version of this code does this, and quite well. Foreground and background colors, font name (with bold/italic support), font size, image size (or automatically detected based on the size of the text), and rotation. I've been working on something like this using GD. Mainly I've been thinking about the interface which (as always) seems to the hardest thing to do properly. It's not an Apache module (though it is designed with mod_perl in mind.) Some form of wrapping module would have to go around it. Hmm. How about I upload the POD so you can see what I mean. htpp://2shortplanks.com/temp/gdti/ Note that this is a work in progress. This code doesn't work yet (though previous hacky versions did.) Yours sounds much more advanced. The basic text support could be extended to allow for images to be overlayed on the text (or placed under the text), or stretch images similarly to how Enlightenment displays window manager themes. Hmm, yes. I have it so the image can be aligned in various ways. It's not quite up to stretching it yet, but we shall see. Other uses planned would be to manipulate existing images. For instance, if an image on a website needs a thumbnail, medium size and full-size view, normally a person must make all versions by hand. If any formatting needs to be done, like borders or drop-shadows, this increases complexity. If a person could just drop an image in a directory, and link to that image, the image could automatically be resized, borders added, drop shadows put in place. The resulting image would then be cached, and outputted. Hmm, getting a little complicated here. My program outputs a GD::Image object when done. The idea is that you can then use GD to implement any of the things you're missing. Also, the stages where it draws the background, the border, the text, and so on are all different methods. This allows you to override these methods with your own ones in subclasses, so you can intercept the image creation at various stages and step in to do things first (e.g. draw to the background before the bg image is drawn) *) URI Arguments Information about what is to be done is passed through the URI. This works for simple tasks like text display, but if anything more complicated is to be done, external configuration files must be used. We'll get to that in a bit. I was working on several different encoding schemes that you could use on the URL. Primarily these were: * Base64 alike encoding * A scheme where was replaced with _ and entities could be used Primely I'm only concerned about the text that you want rendered. Everything else was going to be read from a config file/set in the httpd.conf. I was also planning to implement Template Toolkit plugins to allow you to easily create these images. Essentially, arguments are passed using the PATH_INFO HTTP header. We want the browser to think this is an actual file, instead of a dynamically generated image, so that the browser is more inclined to cache the content. So, a typical query would be: http://localhost/genText/font=ArialBold;size=24;fgcolor=#ff; bgcolor=#00;rotate=90;text=This+Is+The+Text This is indeed a key concept. More importantly I designed my schemes so that they could actually be saved to disk with that filename. One possible idea would be to place the image creation in an ErrorHandler which returns the image and writes it to the correct location on disk. Thus the next time the image is called the perl code is skipped all together and the image is simply sucked off of the disk. I think Randal did a column on something like this a while back. *) Configuration Files I was thinking of using a system accessible in the httpd.conf for the apache module. The real important part here, is the name attribute of any element, as this identifies where input can be indicated. In my scheme each location was a different font. So: http://twoshortplanks.com/f/xmason/1st.jpg Is the image 1st in the xmason style. (yes, that link works) An important aspect is that styles in my system can be created from other styles using the -clone() method. So for example, to create heading2 you could use: my $heading2 = $heading1-clone(text_size = ($heading1-text_size() * 0.8)); All the other attributes would stay the same (colour, background image etc, etc.) The configuration file should reflect that. *) Caching Schemes I hadn't really considered caching systems. Sounds good. Note: To prevent the filesystem from filling up, due to DoS attacks, it may be prudent to have a cron job periodically cull files that have the oldest access time. Or have the handler do it itself after it's returned an image. You'd also want the handler
Re: [RFC] Dynamic image generator handler
Michael == Michael A Nachbaur [EMAIL PROTECTED] writes: Michael This is a mod_perl handler, not directly tied in with my Michael content management system, but is/will be used extensively by Michael it. The premise is to dynamically generate images, cache Michael them, and present them to browser clients. The URI, as well Michael as Apache configuration directives, is used to determine what Michael is to be generated. Like http://www.stonehenge.com/merlyn/LinuxMag/col33.html perhaps? Been there, Done that. Feel free to steal the code. -- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 [EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/ Perl/Unix/security consulting, Technical writing, Comedy, etc. etc. See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Re: [RFC] Dynamic image generator handler
On Fri, 10 May 2002 08:32:55 +0200 Robert [EMAIL PROTECTED] wrote: Take a look at Apache::ImageMagick In my benchmarks I ran, ImageMagick was way slower than GD. I wrote a little test, rendering a little text image of 120x30. With ImageMagick, I was getting 0.3 rps, and under GD with similar circumstances I was getting 1.5rps. I'm sure I could've optimized the ImageMagick one a bit further, but that quick test settled it for me. I looked at Apache::ImageMagick last night however, and although it seems pretty usefull, it doesn't really address what I want to do with my module. -- -man Michael A Nachbaur PGP Public Key at http://www.nachbaur.com/pgpkey.asc PGP Key fingerprint = 83DC 7C3A 3084 6A21 9A3F 801E D974 AFB4 BFD7 2B6F
Re: [RFC] Dynamic image generator handler
On Fri, 10 May 2002 10:52:31 +0100 (BST) Mark Fowler [EMAIL PROTECTED] wrote: The basic text support could be extended to allow for images to be overlayed on the text (or placed under the text), or stretch images similarly to how Enlightenment displays window manager themes. Hmm, yes. I have it so the image can be aligned in various ways. It's not quite up to stretching it yet, but we shall see. I'm not either, all my module supports currently is text. Essentially, arguments are passed using the PATH_INFO HTTP header. We want the browser to think this is an actual file, instead of a dynamically generated image, so that the browser is more inclined to cache the content. So, a typical query would be: http://localhost/genText/font=ArialBold;size=24;fgcolor=#ff; bgcolor=#00;rotate=90;text=This+Is+The+Text This is indeed a key concept. More importantly I designed my schemes so that they could actually be saved to disk with that filename. One possible idea would be to place the image creation in an ErrorHandler which returns the image and writes it to the correct location on disk. Thus the next time the image is called the perl code is skipped all together and the image is simply sucked off of the disk. I think Randal did a column on something like this a while back. Yes, like I say in my caching section, I sort the arguments and then MD5 them, and thats the name of the file on disk. So /tmp/Imagecache/0/1/A/098FAD9 etc. I actually do this process in the URI Transformation phase. I intercept a request, check to see if the given arguments already has a cache entry on disk, and if so, I change $r-filename() to that location on disk. Otherwise, I generate it, and again point to that filename...I then let Apache serve the file. *) Configuration Files I was thinking of using a system accessible in the httpd.conf for the apache module. I want to stay away from httpd.conf-based config files. Although great for most things, the configuration of different image styles can be very site-specific, so I wouldn't want to have to reboot every time someone makes a change. In addition to this, I would like image styles to be editable through my Content Management System; if it's based in the httpd.conf (or even an .htaccess file), that means I'm giving a customer access to the control of the webserver, and that makes the hair stand up on the back of my neck. Rather, I could define an XML configuration file, and use a directive in the httpd.conf (or .htaccess) to point to the relevant configuration file for that site/location. *) Caching Schemes I hadn't really considered caching systems. Sounds good. Note: To prevent the filesystem from filling up, due to DoS attacks, it may be prudent to have a cron job periodically cull files that have the oldest access time. Or have the handler do it itself after it's returned an image. You'd also want the handler to keep a scoreboard of how many images have been generated in the last x minutes to stop generating for things like runaway spiders (though OTOH, this could probably be better handled by another module somewhere else in the chain) I'm trying to keep from tying up the httpd processes unnecessarily. I just want to generate an image, and then pass it off to apache as fast as possible. If I have to disk scan (or even maintain a scoreboard in memory), I'm not sure how that would affect performance. It might not be a bad idea to add a scoreboard, but I don't want it to have to do too much. Looking forward, I would like to be able to use this for more than just text. I'd like my customers to be able to select an image, set the maximum size, check a few boxes or radio buttons to say what formatting options they'd like, and the image is automagically resized without wasting disk space or taking a long time to download. Disk space cheap, CPU cycles expensive. Disk space cheap, CPU cycles expensive, web developer time *really* expensive. So, auto-generate, and load from disk cache. I'm sure there are plenty of other uses for this, but I'll leave it at this. I'm warey of creating a all too powerful module. It's taken me an age to come up with an interface that I think (IMHO) that has a sensible user interface. I wouldn't want to create something too powerful. Unfortunately for me, I need to add these fancy-dancy features. The reason I'm coming back to this module of mine is because I need to have background images behind text, semi-transparency of multi-layered images, and resizing/scaling of images with borders and shadows, etc. -- -man Michael A Nachbaur PGP Public Key at http://www.nachbaur.com/pgpkey.asc PGP Key fingerprint = 83DC 7C3A 3084 6A21 9A3F 801E D974 AFB4 BFD7 2B6F
Re: [RFC] Dynamic image generator handler
On Fri, May 10, 2002 at 10:46:11AM -0700, Michael A Nachbaur wrote: On Fri, 10 May 2002 08:32:55 +0200 Robert [EMAIL PROTECTED] wrote: Take a look at Apache::ImageMagick In my benchmarks I ran, ImageMagick was way slower than GD. I wrote a little test, rendering a little text image of 120x30. With ImageMagick, I was getting 0.3 rps, and under GD with similar circumstances I was getting 1.5rps. I'm sure I could've optimized the ImageMagick one a bit further, but that quick test settled it for me. I looked at Apache::ImageMagick last night however, and although it seems pretty usefull, it doesn't really address what I want to do with my module. I'm using Imlib2 w/ the c interface (http://freshmeat.net/projects/imlib2perl/) I needed antialias lines, alpha's etc. I modified my app to use a 'dbi' like interface for potentially any media driver. The diferent 'media drivers', gd, imlib2, *pdf/*tex etc all have different ideas how to draw a line, circle, polygon, text, add colors etc. Now all I have to do to use diffent libraries such as Media-new(Driver = 'imlib2'), or Media-new(Driver = 'gd'), Media-new(Driver = 'svg'), Media-new(Driver = 'pdflib') etc. There are may libraries out there, gd, imlib, imlib2, libart, povray, gdk, flash, pdfAPI2, pdflib, tex, latex, svg, imager, imagemagic, ... There are may good reasons to be able to 'just drop in' a driver ... just look at why the unified interface 'DBI' was developed for RDBM's . Ed
Re: [RFC] Dynamic image generator handler
On Wed, May 08, 2002 at 01:42:42AM -0700, Michael A Nachbaur wrote: This is an request for comments. If you don't care about dynamic image generation with mod_perl, or don't care about offering or reading about suggestions, you can safely ignore this. Also, be forewarned, this was written in StarOffice, and then copied/pasted into my email program, and hand tweaked, so some things may not have made the transition properly. Dynamic Image Manipulator - *) Overview This is a mod_perl handler, not directly tied in with my content management system, but is/will be used extensively by it. The premise is to dynamically generate images, cache them, and present them to browser clients. The URI, as well as Apache configuration directives, is used to determine what is to be generated. *) Basic Uses The most basic uses of this application will to dynamically generate TTF text for titles, buttons, sidebars, etc. The current version of this code does this, and quite well. Foreground and background colors, font name (with bold/italic support), font size, image size (or automatically detected based on the size of the text), and rotation. The basic text support could be extended to allow for images to be overlayed on the text (or placed under the text), or stretch images similarly to how Enlightenment displays window manager themes. Other uses planned would be to manipulate existing images. For instance, if an image on a website needs a thumbnail, medium size and full-size view, normally a person must make all versions by hand. If any formatting needs to be done, like borders or drop-shadows, this increases complexity. If a person could just drop an image in a directory, and link to that image, the image could automatically be resized, borders added, drop shadows put in place. The resulting image would then be cached, and outputted. *) URI Arguments Information about what is to be done is passed through the URI. This works for simple tasks like text display, but if anything more complicated is to be done, external configuration files must be used. We'll get to that in a bit. Essentially, arguments are passed using the PATH_INFO HTTP header. We want the browser to think this is an actual file, instead of a dynamically generated image, so that the browser is more inclined to cache the content. So, a typical query would be: http://localhost/genText/font=ArialBold;size=24;fgcolor=#ff; bgcolor=#00;rotate=90;text=This+Is+The+Text Resizing an image could be accomplished by doing: http://localhost/genImage/source=/images/ducks.jpg;scale-ratio=1:1; width=120;height=80;border-size:1px;border-color:#00; shadow-color:#00;shadow-angle:270;shadow-distance:5px This would resize an image to the indicated width/height. The scale-ratio argument would limit the width/height ratio, so the maximum dimension would be used. The other attributes are obvious. *) Configuration Files Lets assume that we are going to scale an image, add borders to it which consist of other images, and add text captions over the image. This would result in such a long URI, that browsers would probably truncate it. In addition, providing direct access to the browser opens up possibilities for DoS attacks. Therefore, a configuration file should be used. The config file must be flexible enough to allow a web page to provide various input, but have certain defaults set, and restricted. The proposed solution would be to have a config file that has preset default templates that the input arguments augment. For instance: genimage preset name=thumbnail-image image style border-style: solid; border-color: #00; border-width: 1px; shadow-distance: 5px; shadow-angle: 270; !-- or something like 1.2rad -- shadow-color: #00; /style content name=src/ /image image style href=/css/watermark.css/ !-- The above-referenced file has the following contents: opacity: 80%; position: top; -- content/images/watermark.gif/content /image text style font-face: Arial; font-size: 10px; color: #00; border-style: solid; border-color: #ff; opacity: 80%; text-align: right; /style contentCopyright copy; 2002 Foo Bar Industries/content /text text style font-face: Arial; font-size: 14px; color: #ff; text-align: left; position: top; /style content name=date/ /text /preset /genimage As you can see, the above configuration file uses CSS. It makes sense to leverage that, although I'm not certain how difficult it would be to interface with CSS files. As far as I know, there are Perl CSS parsers, but I have yet to use them. The
Re: [RFC] Dynamic image generator handler
On 10 May 2002 06:39:47 -0700 [EMAIL PROTECTED] (Randal L. Schwartz) wrote: Like http://www.stonehenge.com/merlyn/LinuxMag/col33.html perhaps? Been there, Done that. Feel free to steal the code. Like that, but a bit more so. And I'd like to avoid ImageMagick like the plague. -- -man Michael A Nachbaur PGP Public Key at http://www.nachbaur.com/pgpkey.asc PGP Key fingerprint = 83DC 7C3A 3084 6A21 9A3F 801E D974 AFB4 BFD7 2B6F