1

Topic: Text logo mask

Hi.

One side project again:

I had to write a script, that draws a short text on an image (and I have another idea where I could use this too).

Getting the size and position correct took some dedective work as everything, that happens between fonts, dot size, textlayouts, pixels, doubles, floats and  ints follows logic of it's own -- all that is needed is there though and I did not even try to use things like AffineTransforms on this one.

Hmm... The page-engine arranges stuff here in it's own way tongue .. .I'm splitting this into two posts.

Last edited by peteihis (June 20, 2017, 10:39 am)

Post's attachments

SVG_MASK.png, 46.35 kb, 1024 x 1024
SVG_MASK.png 46.35 kb, 17 downloads since 2017-06-20 

...there's more to the picture than meets the eye...

2

Re: Text logo mask

And here's the script. You need to edit, what you want into the beginnig of the script. Once you get a picture, you can save it. smile

/**
    Text logo mask creator
    by Petri Ihalainen 2017

    Edit the values into the beginning of the scripit. You can also 
    choose which elements to draw and in what color. I think the 
    variable names explain themselves. I also left some options here 
    commented out. Then just hit 'Execute' on the editor. 
    
    When yo have the picture, you can save it, if you like.
*/

import java.awt.*;
import java.awt.font.*;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
import javax.imageio.ImageIO;

int size = 1024;  // Size if the image
String text;
//text = "HELLO!";
//text = "HDR";
text = "SVG";
//text = "GRAY";
//text = "H";
//text = "RGBA";
//text = "RGB";
//text = "XXXX";
//text = "Agility";

String fontName;
//fontName = "Times New Roman";
//fontName = "Gadugi";
//fontName = "Arial";
//fontName = "Courier New";
fontName = "Gabriola";

int style;
//style = Font.PLAIN;
//style = Font.BOLD;
//style = Font.ITALIC;
style = Font.BOLD + Font.ITALIC;

// Ratio must be > 1.0
// The text field diameter is 'size/ratio'
 
double ratio;
ratio = (1+Math.sqrt(5.0))/2.0; // Golden mean
//ratio = Math.sqrt(2);

Color textColor = Color.white;
Color referenceColor = new Color(63,63,63);
Color padColor = new Color(31,31,31);

boolean drawText = true;
boolean fillPad = false;
boolean drawReferences = true;

// It may be worth it to try with a few consequential 
// loop values, say 100 - 108. The text fit may wary a bit.

int loop = 101;

// =====================
// THE WORK BEGINS HERE
// =====================

Font font;
TextLayout textLayout;
Rectangle2D textBounds;
double tw, th, fontSize, fontSize0, textDiag, textDiagLast, factor;

BufferedImage logoPicture = new BufferedImage(size,size, BufferedImage.TYPE_INT_RGB);
Graphics2D g = logoPicture.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
font = new Font(fontName, style, 10);

for (i = 0; i < loop; i++)
{
    textLayout = new TextLayout(text, font, g.getFontRenderContext());
    textBounds = textLayout.getBounds();    
    tw = textBounds.width;
    th = - (new TextLayout("H", font, g.getFontRenderContext())).getBounds().y;
    fontSize = font.getSize2D();
    textDiag = Math.sqrt(tw*tw + th*th);
    
    factor = Math.pow((size/ratio)/textDiag,1.0/8.0);

    font = font.deriveFont((float)(factor*fontSize));    
    textDiagLast = textDiag;
    
    // This is to follow up the development of the size of the text
    // Usually it starts to loop between a couple of values around the ideal
    
    //println(font.getSize2D() + "\t" + textDiag + "\t" + size/ratio);
}

textLayout = new TextLayout(text, font, g.getFontRenderContext());
textBounds = textLayout.getBounds();
int textCornerX = size/2 - (textBounds.width)/2 - textBounds.x;
int textCornerY = (size - (new TextLayout("H", font, g.getFontRenderContext())).getBounds().y)/2;

int r, c;
c = (int)(size/2);

if (fillPad){
    g.setColor(padColor);
    r = (int)(size/2/Math.sqrt(ratio));
    g.fillArc(c-r, c-r, r*2, r*2, 0, 360);
}

if (drawReferences){
    g.setColor(referenceColor);
    // crosshairs
    g.drawLine(c, 0, c, size);
    g.drawLine(0, c, size, c);
    // box
    g.drawLine((int)(c-tw/2), 0, (int)(c-tw/2), size);
    g.drawLine((int)(c+tw/2), 0, (int)(c+tw/2), size);
    g.drawLine(0, (int)(c-th/2), size, (int)(c-th/2));
    g.drawLine(0, (int)(c+th/2), size, (int)(c+th/2));
    // circles
    r = (int)(size/2/ratio);
    g.drawArc(c-r, c-r, r*2, r*2, 0, 360);
    r = (int)(size/2/Math.sqrt(ratio));
    g.drawArc(c-r, c-r, r*2, r*2, 0, 360);
}

if (drawText){
    g.setColor(textColor);
    g.setFont(font);
    g.drawString(text, textCornerX, textCornerY);
}

g.dispose();

// =====================================
// Display it, if you got this far ;)
// =====================================
BFrame PictureFrame = new BFrame();
BMenuBar bar = new BMenuBar();
BMenu menu = new BMenu("File");
BMenuItem save  = new BMenuItem("Save as ...");
BMenuItem close = new BMenuItem("Close");
BLabel PictureLabel = new BLabel(new ImageIcon(logoPicture));

menu.add(save);
menu.add(close);
bar.add(menu);

save.addEventLink(CommandEvent.class, // PictureFrame, 
    new Object() {void processEvent()
    {
        BFileChooser chooser = new BFileChooser(BFileChooser.SAVE_FILE, "Save image");
        chooser.setSelectedFile(new File(text + "_MASK.png"));
        if (!chooser.showDialog(PictureFrame))
            return;
        String fileName = chooser.getSelectedFile().getName();
        File imageFile = new File(chooser.getDirectory(), fileName);
        ImageIO.write(logoPicture, "png", imageFile);
        return;
    }
});

close.addEventLink(CommandEvent.class, PictureFrame, "dispose");
PictureFrame.addEventLink(WindowClosingEvent.class, PictureFrame, "dispose"); // Close by "red X".

PictureFrame.setMenuBar(bar);
PictureFrame.setContent(PictureLabel);
PictureFrame.pack();
PictureFrame.setVisible(true);

Last edited by peteihis (June 23, 2017, 4:22 pm)

...there's more to the picture than meets the eye...

3

Re: Text logo mask

interesting project, does it do multiple lines/rows?

Im getting ready for a povray project of my own, a procedural mesh modeler that will give very high resolution meshes in povray scene description language.  The idea is that I can do mathematically modeled meshes, piecewise, in a way that will give really good topology.

Also is this standalone java or a script for aoi?

Last edited by doomseer (June 25, 2017, 12:21 pm)

May it be an evening star
Shines down upon you
May it be when darkness falls
Your heart will be true

Thumbs up

4

Re: Text logo mask

does it do multiple lines/rows?

No, unfortunately not. I tested what would happen with a line change character in the text, but that was just ignored.

Also is this standalone java or a script for aoi?

It's a groovy script for AoI. Through probably easy to port into anything java-based:

The story behind is, that it is rather difficult to size and center text perfectly on image editors but this way it happens with precision. --  The images are then used as masks in further processing. (I'm not sure if the mask below is the same one, that I used for the final image, but you get the idea. smile

Last edited by peteihis (July 20, 2017, 1:33 pm)

Post's attachments

HDR_process.png, 368.6 kb, 1024 x 2048
HDR_process.png 368.6 kb, 15 downloads since 2017-06-28 

...there's more to the picture than meets the eye...