18
\$\begingroup\$

Sometimes when I'm bored, I take some text and fill the "holes" in the letters. But isn't filling the holes the most boring thing you can do? I think we should automate it, so we could use our time better.

Standard rules apply.

Input

A string containing sequence of alphanumeric characters (a-z, A-Z, 0-9) and spaces.

Output

Image containing string rendered and holes on it filled. You can use any human readable font as long as it still requires filling the holes. You can either save image to file i.png (in png format) or just display the image.

Image properties:

  • Black text
  • White or transparent background
  • Padding:
    • The dimensions of the image can be maximum two times the dimensions of the text
    • Padding should be same color as background, either white or transparent

Example

Input: Example text

Output: Example output

\$\endgroup\$
  • 2
    \$\begingroup\$ Related. (same challenge, different scoring.) \$\endgroup\$ – Martin Ender Feb 13 '16 at 15:43
  • \$\begingroup\$ Is there a minimum font size for the letters (in pixels)? \$\endgroup\$ – Martin Ender Feb 13 '16 at 15:44
  • \$\begingroup\$ Yes, lets say it is 12px \$\endgroup\$ – Hannes Karppila Feb 13 '16 at 18:57
18
\$\begingroup\$

Bash, 135 bytes

convert +antialias -pointsize 99 label:$1 -fill red -draw 'color 0,0 floodfill' -fill black -opaque white -fill white -opaque red i.png

Uses ImageMagick (convert).

Sample output:

sample

convert
  +antialias                              # disable antialiasing
  -pointsize 99                           # annoyingly necessary (see below)
  label:$1                                # draw input text
  -fill red -draw 'color 0,0 floodfill'   # flood fill from (0,0) with red
  -fill black -opaque white               # replace all white with black
  -fill white -opaque red                 # replace all red with white
  i.png

Disabling antialiasing is required because otherwise antialiased interior parts of the letters wouldn't flood fill. Setting the font to a large size is also required because some fonts have "gaps" in letters that should have "holes" in them at small font sizes (in my tests, the a wasn't filled at the default small font size).

\$\endgroup\$
8
\$\begingroup\$

Mathematica, 83 bytes

ImageSubtract[s=Binarize@Rasterize@Style[#,FontSize->99],DeleteBorderComponents@s]&

enter image description here

An unnamed function that takes a string as input and returns an image object. The idea is to use DeleteBorderComponents to keep only the holes and then subtract those from the original image.

\$\endgroup\$
  • 3
    \$\begingroup\$ The funny thing is that Mathematica wins often even with long builtin names like ImageSubtract and DeleteBorderComponents. \$\endgroup\$ – J Atkin Feb 13 '16 at 17:21
  • \$\begingroup\$ That's because Mathematica has builtin names for many things - you don't need to create your own functions often. \$\endgroup\$ – ASCII-only Feb 14 '16 at 5:35
4
\$\begingroup\$

SmileBASIC, 38 bytes

??INPUT S$GPUTCHR.,2,S$,2,2,8GPAINT.,0

Draws black* text on the black background, then uses the built in "paint bucket" function to fill everything outside the text with white.
*(actually I used 00000008, which looks identical to transparent, but is treated as a different color)

enter image description here

\$\endgroup\$
2
\$\begingroup\$

Eats away at the text a bit, but there's also a canvas-based solution:

JS, 610 bytes

function o(a,b){return a[b]+a[b+1]+a[b+2]}x=prompt();l=x.length;c=document.createElement("canvas");document.body.appendChild(c);h=33;w=18*l;c.height=h;c.width=w;n=255;m=764;t=c.getContext("2d");t.fillStyle="white";t.fillRect(0,0,w,h);t.fillStyle="red";t.fillRect(0,2,w,h);t.font="900 30px Courier";t.fillStyle="black";t.fillText(x,0,25);d=t.getImageData(0,0,w,h);f=0;q=d.data.length;for(i=0;i<20;i++){for(j=0;j<q;j+=4){f=d.data;if(o(f,j)>0&&(o(f,j-w*4)>m||o(f,j+w*4)>m||o(f,j-4)>m||o(f,j+4)>m)){f[j]=n;f[j+1]=n;f[j+2]=n}}}for(k=0;k<q;k+=4){f=d.data;if(f[k+1]<1){f[k]=0;f[k+1]=0;f[k+2]=0}}t.putImageData(d,0,0)

enter image description here

\$\endgroup\$
2
\$\begingroup\$

Postscript 273

[was originally posted to the related challenge, but I never implemented the counting.]

Renders each character normally, to get the correct spacing to advance, then takes all the curves which describe the glyph and fills each one. Normally the interior and exterior curves are described with different orientations, so a fill will leave the interior empty, regardless of whether it's using the non-zero winding rule or even-odd rule. Filling separately, it all gets filled.

/Courier 9 selectfont
9 9 moveto{( ) dup 0 4 3 roll put currentpoint 3 2 roll
dup show currentpoint 3 2 roll 5 3 roll moveto
true charpath[[{/moveto
cvx}{/lineto cvx}{/curveto cvx}{/closepath cvx]cvx[}pathforall
pop]]{exec currentpoint fill moveto}forall pop moveto}forall

Indented:

/Courier 9 selectfont
9 9 moveto
{
    ( ) dup 0 4 3 roll put
    currentpoint 3 2 roll
    dup show
    currentpoint 3 2 roll
    5 3 roll moveto
    true charpath
    [ [{/moveto cvx}{/lineto cvx}{/curveto cvx}{/closepath cvx]cvx[}
       pathforall pop] ]
    { exec currentpoint fill moveto } forall
    pop moveto
} forall

Usage. String object is expected to be on the stack when the program starts. Extra scaling just to make it visible.

$ gs -c '7 7 scale(Example Text)' -f courier.ps

snip from output

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.