How you can dynamically place different image templates on a web page.

I have

  • A bunch of fabric patterns (simple jpg files)
  • Image for each letter of the alphabet (blank white background)

I want the page to look like this: http://www.craftcuts.com/hand-painted-wooden-letters-single-patterns.html

but instead of having it as a static page, I would like the user to be able to:

  • Enter your name
  • Select a template (one of the jpg files)

and then display that name in this template.

Obviously, I could create separate jpg for each combination of letters (now I have jpg for each letter with white color) and templates, but I wanted to find out if there was a more elegant way to encode this so that it dynamically puts one image in the letter in another.


EDIT: In my initial post, I suggested it should be front-end (javascript), but if it simplifies (as several people asked what the backend is), my back end is asp.net-mvc, so if there is any- then the solution is to build it on the server and send it to the client, I am more than happy to use this.

+7
html dhtml image asp.net-mvc jpeg
source share
9 answers

You can apply background images to images using CSS, and then use the loading of transparent .png images for letters.

I mocked him:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Untitled Document</title> <style type="text/css"> img.leaves { background:url("leaves.png"); } img.lights { background:url("lights.png"); } </style> <script type="text/javascript"> function makeText() { var text = document.getElementById('text').value.toUpperCase(); var pattern = document.getElementById('pattern').value; for(var i=0; i<text.length; i++) { var img = document.createElement('img'); img.src=text[i]+'.png'; img.className=pattern; document.getElementById('textArea').appendChild(img); } return false; } </script> </head> <body> <form onsubmit="return makeText();"> <p><label for="text">Enter your text</label> <input type="text" name="text" id="text" size="20"></p> <p><label for="pattern">Choose a pattern</label> <select id="pattern"><option value="leaves">Leaves</option><option value="lights">Lights</option></select></p> <p><input type="submit" value="Make!"></p> </form> <div id="textArea"></div> </body> </html> 

and you can also see it in action .

alt text http://www.subdimension.co.uk/files/1/SO/A.png <this is one of the cutouts of the letters (hard to see!)

alt text http://www.subdimension.co.uk/files/1/SO/leaves.png and one of the background images.

I was bored in G, so you can only write words containing ag, it is also a bit lazy because it has only upper case and there are only 2 patterns, but hopefully this should be enough to give you an idea

+15
source share

You can use ImageMagick libraries to make any combination of overlays your hearts and your users desire. Thus, you are not limited to just something simple that can be achieved using CSS.

ImageMagick Examples

+11
source share

The easiest way to do this with Javascript is probably to have an image mask for each letter and apply it over the template. By image masks, I mean a simple image, completely black (or white, or whatever you like) with a β€œcut out” transparent part in the form of a letter. You can simply overlay this on the template file to get the desired effect.

 <div style="background: url(pattern.jpg)"> <img src="letter_a.png" /> </div> 

You can dynamically change img src and div background url to switch patterns and letters. You can also dynamically create new divs based on user input.

Please note that this will not work easily in IE6 due to transparent PNG.

Alternatively, you can generate the image dynamically on the server using something like gd , which would be a little more attractive, but ultimately more flexible.

+6
source share

For users to enter their name, you need a text box. You will also need a button that launches a Javascript function that checks the value of the text field and displays the letters.

You can use the following code to create letters. You will need a text box with an id and div text box to display the results with the identifier 'output', which you can change. I recommend using the select element to store template parameters (#patternChooser in this example)

 function renderName() { // Get the name to be rendered and the chosen pattern var text = document.getElementById('textfield').value; var pattern = document.getElementById('patternChooser').value; // Iterate over the name and create an element for each letter for(i = 0; i < text.length; i++) { var letter = document.createElement('div'); letter.style.backgroundImage = 'url(' + pattern + '_' + text[i] + ')'; document.getElementById('output').appendChild(letter); } } 

You can use the following CSS to apply some positioning to the letters (adjust the c value and the height relative to your images):

 #output div { margin-left: 10px; width: 50px; height: 100px; float: left; } 

You will need to name your images as follows: flowerpattern_a.png, brickpattern_j.png, etc.

If you want the letters to be displayed in real time, you can use Javascript onkeyup () to run a function that checks the last character of a text field and creates an element for it.

Sprites

You can also use a sprite to improve performance. Put all images for letters in one image. You set this image as the background for each letter. Quick reading of CSS sprites: http://css-tricks.com/css-sprites/ You can add background-image: url(sprite.png); into the CSS snippet above. Instead of just setting backgroundImage with Javascript, you will need to set the background position of the letter ( letter.style.background-position = '100px 200px' )

Font Attachment

If you have fonts to use: there are many options for embedding fonts, such as Typeface and Cufon . I think that the most enjoyable for work is the use of the font. It is fast and the text will behave like any other text.

If you received your .TTF Truetype font, you will need to convert the font to .EOT for use with Internet Explorer. You can also add SVG fonts for full browser coverage. This is actually very simple: you simply add the following snippet to the top of your stylesheet as follows:

 @font-face { font-family: 'GothicCustom'; src: url("LeagueGothic.eot"); src: local('League Gothic'), url("LeagueGothic.svg#lg") format('svg'), url("LeagueGothic.otf") format('opentype'); } 

The advantage of this technique is that it is easy to use, and you have full control over the rendered text, like any other text on your site. You can set the font size, the distance between letters, etc. It reads well here about embedding font font fonts . You can use Microsoft WEFT or TTF2EOT to create .EOT fonts.

For example, your code might look like this.

Javascript

 function renderName() { // Get the name to be rendered and the chosen pattern var text = document.getElementById('textfield').value; var pattern = document.getElementById('patternChooser').value; // Render the text with a class for(i = 0; i < text.length; i++) { var output = document.getElementById('output'); output.style.fontFamily = pattern; output.innerHTML = text; } } 

HTML

 <form> <input id="textfield" type="text" /> <select id="patternChooser"> <option>Flowers</option> <option>Brick</option> <option>Decorative</option> </select> <input type="button" onclick="renderName()" /> </form> <div id="output"></div> 

CSS

 @font-face { font-family: 'Decorative'; src: url("decorative.eot"); src: local('Decorative'), url("Decorative.svg#lg") format('svg'), url("Decorative.otf") format('opentype'); } 

Now it remains only to convert the fonts and import them into the stylesheet.

Of course, you can go with any other font embedding method. Here's an article on font embedding options , but a quick Google will also show you options.

+4
source share

If you are allowed to use something in the background, here is a java solution. You just need a font (name.ttf) with which you enter the letters, but I assume you have this:

(this is inside the doGet method for the servlet)

 String text = "A letter, or any text here";
 File texture = new File (patternTexturePath);

 File fontFile = new File (filePath);
 Font font = Font.createFont (Font.TRUETYPE_FONT, fontFile);
 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment ();
 ge.registerFont (font);


 BufferedImage buffer = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);

 g2 = buffer.createGraphics ();
 g2.clearRect (0, 0, width, height);
 g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING,
                     RenderingHints.VALUE_ANTIALIAS_ON);
 g2.setRenderingHint (RenderingHints.KEY_TEXT_ANTIALIASING,
                     RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
 g2.setRenderingHint (RenderingHints.KEY_RENDERING,
                       RenderingHints.VALUE_RENDER_QUALITY);

 FontRenderContext fc = g2.getFontRenderContext ();
 Rectangle2D bounds = font.getStringBounds (text, fc);

 AttributedString attrStr = new AttributedString (text);
 Rectangle r = new Rectangle (0, 0, width, height);
 attrStr.addAttribute (TextAttribute.FOREGROUND, new TexturePaint (ImageIO.read (texture), r));
 attrStr.addAttribute (TextAttribute.FONT, font);
 g2.drawString (attrStr.getIterator (), 0, (int) -bounds.getY ());

 response.setContentType ("image / png");
 ImageIO.write (buffer, "png", response.getOutputStream ());
 response.getOutputStream (). close ();
+1
source share

Even on the server, this is not a trivial problem, since it is not possible to do a direct Fill () using the color mask that you currently need.

I would rather focus on the existing pixels, perform a search and write a sample pixel in the resulting image if the image in the letter is not white:

 Graphics g = Graphics.FromImage(letterImg); Brush brush = new System.Drawing.TextureBrush(patternImg); for (int x=0;i<letterImg.Width;i++) for (int y=0;y<letterImg.Height;y++) { Color mask = img.GetPixel(x,y); //Color pattern = patternImg.GetPixel(x % patternImg.Width, y % patternImg.Height); if (mask != Color.White) { g.FillRectagle(brush,x,y,1,1); } } 

And then find the naming scheme to cache them on disk after creation, so you only need to display the letter combination ↔ once.

+1
source share

GDI + works fine under ASP.NET. (WPF used, but then was broken with the service pack. Not sure if it works again again).

Creating images on the server side is quite simple - the trick connects them to requests on the client side. I used the stack view - my article here:

http://www.hackification.com/2008/10/29/stack-based-processing-part-2/

+1
source share

After confirming with OO (poster), I wanted to throw Flash into the mix.

The advantage of Flash is that it has really good anti-aliasing and great typography support (especially with CS4). You can select the entire interface in Flash, where you enter the letters with the pattern directly or simply display the SWF result in accordance with the parameters defining the name and pattern.

Personally, I would do all this in Flash, providing the interface with additional templates, such as JSON. But the main steps you can take are

create a form with an input for the name and a selection box for templates

display flash file with parameters patterntype.swf? name = flash & pattern = disco.png

The basic concept is that the text is set as a mask for the template. I checked a quick check in flash to check the performance of the template splitting (and if it really works)

 package { import flash.display.MovieClip; import flash.display.Loader; import flash.net.URLRequest; import flash.events.Event; import flash.display.Sprite; import flash.display.Bitmap; import flash.display.BitmapData; public class PatternType extends MovieClip { /* library element, use the textfield to change the font */ public var nameDisplay:NameDisplay; private var loader:Loader; /* parameters, you can pass these as request parameters, or make a javascript call to get/set them */ private var pattern:String = "pattern.png"; private var nameString:String = "Heidi Klum"; private var container:MovieClip; public function PatternType() { container = new MovieClip(); addChild(container); nameDisplay = new NameDisplay(); nameDisplay.txt.text = nameString; nameDisplay.cacheAsBitmap = true; //mask wont work without this. container.addChild(nameDisplay) container.mask = nameDisplay; loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handlePatternLoaded); loader.load(new URLRequest(pattern)); } private function handlePatternLoaded(e:Event) { trace("complete"); var bmp:Bitmap = e.target.content as Bitmap; var rows:int = Math.ceil(stage.stageHeight / bmp.height); var cols:int = Math.ceil(stage.stageWidth / bmp.width); //tile the texture for(var i:int = 0; i < cols; i++) { for(var j:Number = 0; j < rows; j++) { var b:Bitmap = new Bitmap(bmp.bitmapData.clone()); bx = i * bmp.width; by = j * bmp.height; container.addChild(b); } } } } } 

When it all depends on the wishes of users, you can create a new Bitmap object from the result and send data to a server that can write data directly to a bitmap image file (possibly also jpeg).

A few things Flash can sell a little more:

  • you can rotate the text
  • use exotic fonts
  • use different letter patterns
  • scale text
  • use custom image filters
  • moving in three-dimensional space (translation rotation x, y, z, perspective)
  • Save result as image
+1
source share

Read the link below where you will find information on the alonmg dynamic loader with an example http://thecodecentral.com/2008/02/21/a-useful-javascript-image-loader

0
source share

All Articles