1. Merging Of Images

------=_NextPart_000_01BC4871.353FA8C0


Okay, seeing that people are concerned about the lack of EuphoriaSpeak in
this mailing list, I decided to kill two birds with one stone. I have a
question about a design problem I've encountered during my coding of "A
Beginner's Guide To Euphoria" 2.00. Not only will this make the topic
worshippers happy, I'll get some good advice from the graphics pros.

I'm attempting to overlay a W shaped graphics image (in the form of a
chapter index list) over another graphics image that contains changing
data. I've included the image as part of this letter in GIF format. My
apologies to those who feel this is unnecessary overhead, but I feel
studying the image will help you understand my problem. Because the image
is W shaped, bits of the background screen should appear between the
"fingers" of the image. This means simply doing a save_image() of the
background followed by a display_image() won't work. I've gotten the W
image to appear properly on the screen but it takes a little time because I
merge bits of the background between the fingers before displaying. To do
this takes 1 second on my P-90 but 4 seconds on a 486SX-25. Not acceptable.

I've tried xor_bits(), and_bits() and or_bits() to merge the two images
together. It works VERY fast but the resulting union causes the W image to
appear in different colours. I have two alternatives left. One is to
display the W image in 4 separate display_images() as rectangular shapes,
but that would make the W image appear in steps, and would be particularly
noticable on a slower machine. The other would be to redo the W image in
false colours so the resulting and_bits(), or_bits() or xor_bits() would
make it appear in the correct colours.

Any help from the graphics experts of this listserv would be appreciated.

Thanks

David Gay
http://www.interlog.com/~moggie/Euphoria
"A Beginner's Guide To Euphoria"




------=_NextPart_000_01BC4871.353FA8C0

new topic     » topic index » view message » categorize

2. Re: Merging Of Images

re: merging of images
 ---------------------
I had a similar problem with putting up text in graphics mode. The only way
I could get text to the screen without the default background color was to
OR it to the screen - but the colors showed up inverted.

I couldn't build an inverse color lookup table, because different color
backgrounds caused different colors to appear. It finally occured to me that
if I wrote a character to the background using the *background* color, I'd
get a black character on the screen. I could then display the character
again, this time using the correct foreground color.

You may be able to create a mask for your image, instead of resorting to
false colors.


putsyx
 ------
I had seen it in someone else's "windows" program, and wondered if it would
be useful in my graphics-mode GUI. I re-wrote your putsxy routine so that it
can use the .FNT files that are included in my Fonter program.
 Unfortunately, it's still to slow for a text-intensive application like
mine even on a pentium.

I'm including the routine and a demo, but *not* any font files - they're
just too darned big, even compressed. You can download them from Robert's
page if you are interested. The font file DEFAULT.FNT is required. If there
are any other fonts in the directory, the demo will list their names using
their font.

Good points:
   - About twice as fast
   - Can use multiple font files

Bad points:
   - Font files required
   - Font file takes a moment to load
   - Can't directionally print

If you find this interesting, I can clean it up a bit.

I'm thinking of going back to my Fonter program some time and adding a
binary font format, for size and speed. Right now, I've got about 25 font
files, but they come to about a 1 Meg - too much for me to e-mail to Robert.
Binary format would take a giant bite out of this size.

If anyone in interested, let me know and I'll update the Fonter program, and
add the new fonts (after finishing the editor, of course...)

 -- David Cuny



 -- START OF PUTSXY.E --------------
 -- I made a number of changes to your routine. Some of them are for
 -- speed; others allow you to load my font files.

 -- here, i declare the font table. there are two advantages:
 -- 1. undefined fonts are blank, so they need no special handling
 -- 2. i can use ascii code + 1 as indexes, instead of indexed lookup

    sequence font_table
    font_table = repeat( repeat( repeat( 0, 8 ), 16 ), 256 )



 -- this procedure loads a font file into the sequence.
 -- it's a bit ugly. binary font files would be simpler.

global procedure load_font_file( sequence file )

    -- load one of my font files into the table

    atom handle         -- file handle
    integer ascii       -- font being looked at
    sequence s          -- line read from file

    -- open the file
    handle = open( file, "r" )
    if handle = -1 then
        clear_screen()
        puts( 1, "Unable to load font file " & file & ".\n" )
        abort( 0 )
    end if

    -- read the entire file
    while 1 do

        -- get a line
        s = gets( handle )

        -- end of file marker?
        if match( "end", s ) then

            -- end marks end of file
            exit

        -- beginning of font definition?
        elsif s[1] = '-'
        or    s[1] = '#' then

            -- code, or number?
            if s[1] = '-' then

                -- ascii code follows the "-"
                -- example:  "-a" means "define character 'a'"

                ascii = s[2]

            else
                -- number follows
                -- example: "#32" means "define ascii character 32"

                -- convert number that follows
                -- there is a euphoria routine that does this, but
                -- i'm too lazy to look it up

                ascii = 0
                for i = 2 to length( s ) do
                    if s[i] = '\n'
                    or s[i] = ' ' then
                        exit
                    else
                        ascii = ( ascii * 10 ) + ( s[i] - '0' )
                    end if
                end for

            end if

            -- offset by 1. this handles code 0

            ascii = ascii + 1

            -- next 16 lines are the font, in an 16x8 grid
            -- 'x' indicates a bit on
            -- '.' indicates a bit off

            -- 16 bits high
            for i = 1 to 16 do

                -- get a line
                s = gets( handle )

                -- 8 bits wide
                for j = 1 to 8 do
                    -- convert x to 1, other to 0
                    font_table[ascii][i][j] = ( s[j] = 'x' )
                end for

            end for

        -- hopefully a comment.
        else

            -- ignore

        end if

    end while

    close( handle )

end procedure





global procedure putsxy(sequence pixel_loc, sequence display_text,
                        atom foreground, atom background)


    -- My version of putsxy
    -- Direction is not used, so I can't print a string vertically.

    -- Rather than print the characters out one byte at a time, I append
    -- them onto the end of the image. When the string is complete, I can
    -- print the image.

    -- Since I have a complete table of fonts (some may be blank), I can
    -- access the fonts directly, rather than indirect them.


    sequence image  -- the image of the text

    -- text is 16 bits tall
    image = repeat( {}, 16 )

    -- lookup each byte
    for i = 1 to length(display_text) do
        -- for each scan line
        for j = 1 to 16 do
            -- add 8 bits of character
            image[j] = image[j] & font_table[display_text[i]+1][j]
        end for
    end for

    -- convert 1 and 0 to foreground and background colors
    image = image * (foreground-background)
    image = image + background

    -- display the image
    display_image(pixel_loc,image)

end procedure


 -- load the default font into memory
    load_font_file( "default.fnt" )



 -- END OF PUTSXY.E --------------



 -- START OF DEMO.EX ------------
 -- Demo of re-written putsxy()
 --   Displays all the font files in the directory, using each
 --   file's font.

include graphics.e
include image.e
include putsxy.e
include file.e

 -- graphics mode available?
if graphics_mode(18) then -- try other modes
   puts(1, "Mode Failure\n")
   abort(100)
end if

 -- read and display the fonts
sequence fontList
integer line, col
line = 1
col = 1
fontList = dir( "*.fnt" )
for i = 1 to length( fontList ) do
    load_font_file( fontList[i][D_NAME] )
    putsxy( {col*8, line*16},
        "Font: " & fontList[i][D_NAME], CYAN, BRIGHT_WHITE )
    line = line + 1
    if line > 25 then
        line = 1
        col = col + 30
    end if
end for


 -- wait for a key
while 1 do
    if get_key() != -1 then
         exit
    end if
end while

if graphics_mode(-1) then
   puts(1, "Mode Failure\n")
   abort(100)
end if

 -- END OF DEMO.EX --------------

new topic     » goto parent     » topic index » view message » categorize

3. Re: Merging Of Images

--=====================_861070287==_

Hi David,

  The usual technic to put an image with irregular contour over another is to
use a black mask that is AND put over the background image before the real
image.
In the case of your W shape you should create a black W on white background.
This mask is AND with the background image. This will create a black W without
disturbing anything else around it. Then OR put the W over the black one.
(The W should be drawn on black backround.)

 I send you a little demo: masking.ex

It display a blue flea on a random background without disburbing the background.








--=====================_861070287==_
 x-mac-type="705A4950"; x-mac-creator="705A4950"

new topic     » goto parent     » topic index » view message » categorize

4. Re: Merging Of Images

> I'm attempting to overlay a W shaped graphics image (in the form of a
> chapter index list) over another graphics image that contains changing
> data. I've included the image as part of this letter in GIF format. My
> apologies to those who feel this is unnecessary overhead, but I feel
> studying the image will help you understand my problem. Because the image
> is W shaped, bits of the background screen should appear between the
> "fingers" of the image. This means simply doing a save_image() of the
> background followed by a display_image() won't work. I've gotten the W
> image to appear properly on the screen but it takes a little time because I
> merge bits of the background between the fingers before displaying. To do
> this takes 1 second on my P-90 but 4 seconds on a 486SX-25. Not acceptable.
>
> I've tried xor_bits(), and_bits() and or_bits() to merge the two images
> together. It works VERY fast but the resulting union causes the W image to
> appear in different colours. I have two alternatives left. One is to
> display the W image in 4 separate display_images() as rectangular shapes,
> but that would make the W image appear in steps, and would be particularly
> noticable on a slower machine. The other would be to redo the W image in
> false colours so the resulting and_bits(), or_bits() or xor_bits() would
> make it appear in the correct colours.
>
> Any help from the graphics experts of this listserv would be appreciated.
>
> Thanks
>
> David Gay

Check out this little routine I just wrote.

It works the same way as display_image(), except that you need to
give it three arguments, instead of just two. The first two are
exactly the same, and the third is just the color you want to see the
background through. With your picture I think it's color 13.

I timed it myself, and got about .22 to .33 seconds on my P-100.

Hope this helps.

Michael Bolin

---------------------------------------------------------
include graphics.e

procedure display_mask_image(sequence pos,sequence image,integer mask_color)
    sequence background,work
    integer draw_y,left_x,color

    draw_y = pos[2]
    left_x = pos[1]
    for y = 1 to length(image) do
        work=image[y]
        background = get_pixel({left_x , draw_y , length(work)})
        for x = 1 to length(work) do
            color = work[x]
            if color != mask_color then
                background[x] = color
            end if
        end for
        pixel(background , {left_x,draw_y})
        draw_y = draw_y + 1
    end for
end procedure
---------------------------------------------------------

new topic     » goto parent     » topic index » view message » categorize

5. Re: Merging Of Images

> I couldn't build an inverse color lookup table, because different color
> backgrounds caused different colors to appear. It finally occured to me
that
> if I wrote a character to the background using the *background* color,
I'd
> get a black character on the screen. I could then display the character
> again, this time using the correct foreground color.
>
> You may be able to create a mask for your image, instead of resorting to
> false colors.

This is a great idea, David. I believe it is possible to create a mask for
this image, even though it is quite a large image. The only thing I have to
work around is the mask colour. Silly me used black in parts of the
background so I'm going to have to use a mask colour other than black. But
I believe your idea will solve my problem, with a noticable improvement in
speed.

Rather than force you to endure yet another series of meaningless
characters as Email (and spare myself the embarassment of screwing up an
attachment for the third time), the image can be seen at
http://www.interlog.com/~moggie/indexscr.gif , in case you want to look at
it again.

I'm glad you improved the putsxy() library routine I wrote a while back.
It's appropriate,  seeing you are the one that allowed us to use special
fonts in our programs. :)...my version wasn't as clever as I thought it was
at the time, particularly because of the number of lines it took to store
each display_image() character. I have since improved on that, allowing the
display of all printable ASCII characters and using much fewer source lines
to do it. The trick is to take each 8 pixel line and convert it to bits,
which is then stored as a single byte thanks to bits_to_int(). This means
only 16 bytes are required to represent a 8 pixel wide, 16 pixel high
image, instead of saying:

{{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}}

as a series of source lines in the program.

If you can come up with even better versions of putsxy(), I certainly want
to know about it. Your future contributions regarding text handling in
graphics mode would be valuable.

Thanks

David Gay
http://www.interlog.com/~moggie/Euphoria
"A Beginner's Guide To Euphoria"

new topic     » goto parent     » topic index » view message » categorize

6. Re: Merging Of Images

> Hi David,
>
>   The usual technic to put an image with irregular contour over another
is to
> use a black mask that is AND put over the background image before the
real
> image.
> In the case of your W shape you should create a black W on white
background.
> This mask is AND with the background image. This will create a black W
without
> disturbing anything else around it. Then OR put the W over the black one.
> (The W should be drawn on black backround.)

Okay, I am going to give that a try.....The trick now is to make a black
image that fits the dimensions and contours of the W shape. The shape is at
http://www.interlog.com/~moggie/indexscr.gif if you have not seen it yet.
If you have, thank me profusely for sending a URL instead of the actual
image :}

Thanks for your help, Jacques :)

David Gay
http://www.interlog.com/~moggie/Euphoria
"A Beginner's Guide To Euphoria"

new topic     » goto parent     » topic index » view message » categorize

7. Re: Merging Of Images

David Gay wrote:

> The trick is to take each 8 pixel line and convert it to bits,
> which is then stored as a single byte thanks to bits_to_int(). This means
> only 16 bytes are required to represent a 8 pixel wide, 16 pixel high

Exactly! That's the format that you need to send it to the video card, as
well.
I didn't do that because I didn't want to deal with a "text" and a
"compressed"
version of the file in Fonter, but because of the size, I'll be moving to
that
format, and writing a txt2fnt/fnt2txt routine.

Here's a chance for me to show my ignorance: how do you redefine the
character
set in graphics mode? I know that it can be done, but it's a little bit
different
than text mode, and I can't quite figure it out.

Thanks.

 -- David Cuny

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu