Can't draw images alpha AND stretch...

Posted by Asmodeusbrooding on Tue 01 Nov 2022 09:50 AM — 20 posts, 55,221 views.

#0
Hey friends,

I've been stuck on this same issue for about five years and still can't solve it..

I am trying to draw an image with a transparent background (alpha) into a hidden miniwindow, then copy it over to another miniwindow and stretch it. OR, draw it stretched into a hidden miniwindow, and then draw it using WindowDrawImageAlpha into another window. I've basically tried every combination I can think of, doing things like that...



 if WindowInfo("hiddenWindow", 4) == nil then
    --DebugNote("No hidden window, creating it now!")
      WindowCreate (hiddenWindow, 0, 0, 0, 0, 12, 3, ColourNameToRGB("green"))
   end
      -- lets check if its a chest
chestX = GetPluginVariable("b6eae87ccedd84f510b74714", "chestLocationX") or nil
chestY = GetPluginVariable("b6eae87ccedd84f510b74714", "chestLocationY") or nil

if tonumber(chestX) ~= nil and tonumber(chestY) ~= nil and tonumber(room.x) ~= nil and tonumber(room.y) ~= nil then
   if tonumber(room.x) == tonumber(chestX) and tonumber(room.y) == tonumber(chestY) then
      alphaImageId = "chest"
      chestPath = "worlds\plugins\images\chest.png"
        if WindowLoadImage (hiddenWindow, alphaImageId, chestPath) == 0 then
          WindowResize (hiddenWindow, WindowImageInfo(hiddenWindow, alphaImageId, 2), WindowImageInfo(hiddenWindow, alphaImageId, 3), ColourNameToRGB("green")) -- resizes the miniwindow with a green background: wish i could just do NO color, heh
          WindowDrawImageAlpha(hiddenWindow, alphaImageId, 0, 0, 0, 0, 1) -- draws the chest with 100% opacity, withn alpha layer in tact.
          WindowImageFromWindow(win, alphaImageId, hiddenWindow) -- grabs the chest from hiddenWindow
          WindowDrawImage (win, alphaImageId, left, top, right, bottom, 2) -- draws the chest
        end
    end
end


I basically
1. Create the hidden miniwindow
2. Resize the hidden miniwindow
3. Draw the alpha image
4. Transfer it to the other window
5. Draw the image stretched.

I have tried by using step 5 as 3 and 3 as 5, and I have tried by using WindowTransformImage as well after the resize/draw, and before the final draw.

I've tried everything I can possibly imagine..

I've also printed the colors to myself to figure out where I'm going wrong..

FIRST PRINT BEFORE RESIZE: 0
PRINT AFTER ALPHA DRAW: 32768
PRINT BEFORE DRAWING: 41754
AFTER THE DRAW: 32768


The final image still has a green background..
Seen here:
https://cdn.discordapp.com/attachments/660703844967251973/1036930462825852938/unknown.png

If I Just use
WindowDrawImage (win, alphaImageId, left, top, right, bottom, 3)
it will draw the image how it should, without the background color, but it won't be stretched...
Seen here

https://cdn.discordapp.com/attachments/660703844967251973/1036930742149726209/unknown.png


I need to do both..

I am trying to draw an image, in this case a CHEST, over a room in my mapper. This would work with all of the other icons I wish to draw as well.
PLEASE HELP!
Amended on Tue 01 Nov 2022 11:23 AM by Asmodeusbrooding
Australia Forum Administrator #1
Before I try reproducing your issue, did you try making the window transparent (flag 4 on WindowCreate)?
#2
Hey Nick,

Indeed I have tried that.


I've actually had a whole army of people try to solve this issue, and seemingly nobody can, which is why I finally turned to you again on helping solve this problem..


Have tried a HUGE combination of WindowImageFromWindow, WindowImageTransform, WindowDrawImageAlpha, WindowResize, WindowGetImageAlpha, etc etc etc..

Somebody mentioned that it might not be supported, and linked me to this article, not sure if that's true.

https://www.gammon.com.au/forum/?id=10517

Anyways, truly, I've put seriously hundreds of hours into trying to solve this and would really appreciate it if you could provide some insight.

The closest we got to anything remotely similar is this, but it's still not the solution I'm looking for.


         WindowCreate (hiddenWindow, 0, 0, 1000, 1000, 3, 4, ColourNameToRGB("black"))
         chestPath = "tmp\chest.png"
         WindowLoadImage (hiddenWindow, alphaImageId, chestPath)
         WindowDrawImage(hiddenWindow, alphaImageId, 0, 0, 0, 0, 1)  
       WindowResize (hiddenWindow, WindowImageInfo(hiddenWindow, alphaImageId, 2), WindowImageInfo(hiddenWindow, alphaImageId, 3), ColourNameToRGB("transparent")) -- resizes the miniwindow with a green background?
        WindowImageFromWindow(win, betaImageId, hiddenWindow) 
        WindowTransformImage(win, betaImageId, left, top, 3, 1.5, 0, 0, 1.5)


If I try drawing stretched there on WindowDrawImage, we have a problem. If I try drawing Alpha later, we have a problem.
I am trying to use the scale arguments in variable ways to make it work how I want it to, but that's pretty difficult.

The main solution I'm looking for is a stretch, so it's guaranteed to be how it should.

A long time ago you mentioned to me that it *should* be possible if I drew to a hidden miniwindow, and stretched it, and drew it alpha using the transparency pixels, but I could not get it to work.

I appreciate your time...


P.S. I know that "transparent" argument in the WindowResize is not real, but it has the same effect as just doing it in BLACK. I tried any color there, just to be clear. I just pasted the "transparent" argument in here may have something to mention about it, though probably not.
Amended on Wed 02 Nov 2022 11:26 AM by Asmodeusbrooding
USA Global Moderator #3
What about loading the image and mask separately and using WindowMergeImageAlpha after resizing both?
Amended on Wed 02 Nov 2022 06:35 PM by Fiendish
Australia Forum Administrator #4

Just so I understand where you are coming from:

  • The images you are loading on top of the main image have an alpha channel?

  • Why don’t you just resize them in advance? Or do you need to draw them different sizes from time to time?

  • Why create a zero-size hidden window? Why not the size of the chest you want?

      WindowCreate (hiddenWindow, 0, 0, 0, 0, 12, 3, ColourNameToRGB("green"))
Australia Forum Administrator #5
Quote:


 if WindowInfo("hiddenWindow", 4) == nil then
    --DebugNote("No hidden window, creating it now!")
      WindowCreate (hiddenWindow, 0, 0, 0, 0, 12, 3, ColourNameToRGB("green"))
   end



This seems inconsistent. Is there a variable hiddenWindow with "hiddenWindow" as its contents? If not, then the WindowCreate will fail. If there is such a variable, why not use it on the WindowInfo line?




I suggest putting "check" around all your function calls to see which ones, if any, are failing, eg.


check (WindowCreate (hiddenWindow, 0, 0, 0, 0, 12, 3, ColourNameToRGB("green")))
Australia Forum Administrator #6
I don't see the need for the hidden window at all. This example loads a main image and puts a couple of chests on it, different sizes. The chests have an alpha channel, which I presume yours must have or the issue you are describing wouldn't exist.


mainImage = GetInfo (60) .. "images/summer_325x244.png"
chestPath = GetInfo (60) .. "images/chest.png"


win = "A" .. GetPluginID ()  -- get a unique name
WindowCreate (win, 0, 0, 365, 285, miniwin.pos_center_all, 0, ColourNameToRGB("white"))  -- create window

alphaImageId = "chest"
mainImageId = "im"


-- load the main image
check (WindowLoadImage (win, mainImageId , mainImage ))

-- load the chest image
check (WindowLoadImage (win, alphaImageId, chestPath))

-- draw the main image into the miniwindow
check (WindowDrawImage (win, mainImageId , 0, 0, 0, 0, miniwin.image_stretch))

-- draw one chest (50% size)
check (WindowTransformImage(win, alphaImageId, 20, 20, miniwin.image_transparent_copy , 0.5, 0, 0, 0.5))

-- draw another chest (80% size)
check (WindowTransformImage(win, alphaImageId, 150, 150, miniwin.image_transparent_copy , 0.8, 0, 0, 0.8))


WindowShow (win,  true)  -- show it 


This is how it looks:






And without the "check" stuff which would slow it down very slightly:


mainImage = GetInfo (60) .. "images/summer_325x244.png"
chestPath = GetInfo (60) .. "images/chest.png"


win = "A" .. GetPluginID ()  -- get a unique name
WindowCreate (win, 0, 0, 365, 285, miniwin.pos_center_all, 0, ColourNameToRGB("white"))  -- create window

alphaImageId = "chest"
mainImageId = "im"


-- load the main image
WindowLoadImage (win, mainImageId, mainImage)

-- load the chest image
WindowLoadImage (win, alphaImageId, chestPath)

-- draw the main image into the miniwindow
WindowDrawImage (win, mainImageId , 0, 0, 0, 0, miniwin.image_stretch)

-- draw one chest
WindowTransformImage(win, alphaImageId, 20, 20, miniwin.image_transparent_copy, 0.5, 0, 0, 0.5)

-- draw another chest
WindowTransformImage(win, alphaImageId, 150, 150, miniwin.image_transparent_copy, 0.8, 0, 0, 0.8)


WindowShow (win, true)  -- show it 

Amended on Wed 02 Nov 2022 10:29 PM by Nick Gammon
#7
Hey Nick,

Thanks for the time on this, but those solutions don't work for what I'm trying to accomplish, as they don't account for the size of the rooms in the map depending on the user zoom level.
I did already use those exact methods.


These images are being drawn onto the mapper, and the mapper can be zoomed in or out, this is why the image needs to be stretched (to the left/top/right/bottom of the mapper tile)
The alpha image needs to stay on the image within each "room" tile on the mapper.


If you draw these images without stretching, when you zoom in the mapper they become thrown out of alignment and size more and more.

It could suddenly end up looking like this

https://media.discordapp.net/attachments/660703844967251973/1036930742149726209/unknown.png

while getting worse and worse in regard to the sizing/alignment depending on zoom.

As far as which of the functions are failing, I've added a print to every single line and none of the functions should be failing.

I will admit, I'm a self taught newbie though, so I'm very open to being wrong, but I did have a few very competent coders try this as well and fail.

I'm looking for a solution that works with existing non-alpha images, where I just stretch the image like this:


WindowDrawImage(win, imageId,  left, top, right, bottom, miniwin.image_stretch)



Here are some example images. Zooming out just makes it worse and worse... Here is the worst first, getting a bit better as you zoom in, and then getting worse again.

https://cdn.discordapp.com/attachments/660703844967251973/1037537989384994846/unknown.png


https://cdn.discordapp.com/attachments/660703844967251973/1037537928563392552/unknown.png

https://cdn.discordapp.com/attachments/660703844967251973/1037537882086322196/unknown.png

https://cdn.discordapp.com/attachments/660703844967251973/1037537823898742894/unknown.png

https://cdn.discordapp.com/attachments/660703844967251973/1037537680604545044/unknown.png
Amended on Thu 03 Nov 2022 01:26 AM by Asmodeusbrooding
Australia Forum Administrator #8
Asmodeusbrooding said:

These images are being drawn onto the mapper, and the mapper can be zoomed in or out, this is why the image needs to be stretched (to the left/top/right/bottom of the mapper tile)
The alpha image needs to stay on the image within each "room" tile on the mapper.


If you draw these images without stretching, when you zoom in the mapper they become thrown out of alignment and size more and more.


I'm not sure I understand you. The code I showed lets you alter the size arbitrarily, right? So the only issue is the position? Can't you change the starting point for WindowTransformImage to account for the zoom level?

Can you post an image or two showing how you want it to look (made up in Gimp or Photoshop or something).
Australia Forum Administrator #9
Quote:

I'm looking for a solution that works with existing non-alpha images, where I just stretch the image like this:


Well, I'm guessing here about what your files are like. How about making up a test case with your background image, and your chest image, and let me manipulate that?

Preferably with the code you are using so I can see how you are going about it. A complete executable example (which I could paste into the Immediate window).
Australia Forum Administrator #10
Quote:

These images are being drawn onto the mapper, and the mapper can be zoomed in or out ...


When the mapper zooms, it just redraws the map with different parameters for the size of each room, the distance they are apart and so on. So you would just correspondingly alter the size and position of your chests or other images.

Or, are you talking about something else?
Australia Forum Administrator #11
Quote:

I am trying to draw an image with a transparent background (alpha) into a hidden miniwindow ...


then:

Quote:

I'm looking for a solution that works with existing non-alpha images ...


First you say you want to work with a transparent background, then you say you want to work with non-alpha images. I'm confused about your requirements here.
#12
Hey Nick, I am not trying to say I want to do it with my non-alpha images, I was trying to say that I want the solution to work the same way that my non-alpha images work: in the way that they stretch to each tile in the mapper. Sorry about that confusion.



Yes, when the mapper zooms in and out it already resizes left/top/right/bottom of each "room", as you know, and usually the image stretches to that "room". I am just looking for the alpha image to stretch to that same "room" in the same way.

A near perfect example of what I'm trying to do, image wise, is this:

https://cdn.discordapp.com/attachments/660703844967251973/1037005144920965190/unknown.png

and THIS is what it looks like if you attempt to draw it stretched in general with the alpha layer.

https://cdn.discordapp.com/attachments/660703844967251973/1036995236376887397/unknown.png

(it is centered, but has that black border)



Here is a short video of what the issue remains to be, with the fix I proposed (which you also proposed later)

https://i.imgur.com/Dx5WBZc.mp4


Notice how all terrain tiles resize accordingly. I just want the alpha image (chest) which is assigned to that same space to be stretched in the same way the terrain tiles are.

It is only a bootleg fix. If I can figure out the calculations to make it zoom a certain way based on the mapper zoom, problem solved, *potentially*, but I'm wondering if there is any other way to do it?

I'm just thinking there really should be an easier way to stretch/draw an alpha image?


P.S.
If you still play Aardwolf, you can try here:

https://github.com/AsmodeusBrooding/Aardwolf/tree/main/GraphicalMapper

This is an older version of the mapper, but it works the same...

Just put the code in the elseif line 714 and try drawing the chest over aylor recall as a test, I guess?
Otherwise, that's not a very MINIMUM test I guess, but I don't know a better way to test than how it's actually being used.
Amended on Thu 03 Nov 2022 10:00 AM by Asmodeusbrooding
#13
One of my friends did this thing, but they had to create 3 miniwindows to test it. This should be testable by you.



<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Friday, August 14, 2009, 6:13 AM -->
<!-- MuClient version 4.43 -->


<muclient>
<plugin
   name="ChestTest"
   id="08fffaaa11346af04a1be9e3"
   language="Lua"
   purpose="Display mobs in room."
   save_state="y"
   requires="4.43"
   version="1.1"
   >
<description trim="y">
<![CDATA[
]]>
</description>
</plugin>

<!--  Get our standard constants -->

<include name="constants.lua"/>
<!--  Triggers  -->

<triggers>
</triggers>
<!-- Aliases -->
<aliases>
</aliases>
<!--  Script  -->
<script>
<![CDATA[
-- Options -----------------------------------------------

function OnPluginInstall ()
    hiddenWindow = "hiddenWindow"
    visibleWindow = "visibleWindow"
    alphaMaskWindow = "alphaWindow"
    alphaImageId = "chest"
    betaImageId  = "beta"
    treeImageId = "tree"

    -- Stretch the chest in a hidden window
    WindowCreate (hiddenWindow, 100, 500, 64, 64, 12, 2, ColourNameToRGB("black"))
    WindowLoadImage (hiddenWindow, alphaImageId, "chest.png")
    WindowDrawImage(hiddenWindow, alphaImageId, 0, 0, 64, 64, 2, 0, 0, 32, 32) 
    
    -- Draw an unstretched alpha mask in a hidden window using the chest
    WindowCreate(alphaMaskWindow, 100, 50, 32, 32, 12, 2, ColourNameToRGB("red"))
    WindowLoadImage (alphaMaskWindow, alphaImageId, "chest.png")
    WindowGetImageAlpha(alphaMaskWindow, alphaImageId, 0, 0, 32, 32, 0, 0);
    --long WindowDrawImage(BSTR WindowName, BSTR ImageId, long Left, long Top, long Right, long Bottom, short Mode, long SrcLeft, long SrcTop, long SrcRight, long SrcBottom);

    
    -- Stretch the alpha mask in a hidden window
    WindowCreate("alphaMaskWindowStretched",100,300, 64, 64, 12, 2, ColourNameToRGB("green"))
    WindowImageFromWindow("alphaMaskWindowStretched", "alphaMaskId", alphaMaskWindow);
    WindowDrawImage("alphaMaskWindowStretched", "alphaMaskId", 0, 0, 64, 64, 2)

    -- just for debugging, show the windows so we know whats inside
    WindowShow(alphaMaskWindow, true)
    WindowShow("alphaMaskWindowStretched", true)
        WindowShow (hiddenWindow,  true)


    WindowLoadImage (visibleWindow, alphaImageId, "chest.png")

    WindowLoadImage (visibleWindow, treeImageId, "cave.png")
    WindowCreate (visibleWindow, 250, 0, 300, 300, 12, 10, ColourNameToRGB("white"))
    WindowTransformImage(visibleWindow, treeImageId, 0, 0, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 64, 0, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 128, 0, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 192, 0, 3, 2, 0, 0, 2);

    WindowTransformImage(visibleWindow, treeImageId, 0, 64, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 64, 64, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 128, 64, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 192, 64, 3, 2, 0, 0, 2);

    WindowTransformImage(visibleWindow, treeImageId, 0, 128,   3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 64, 128,  3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 128, 128, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 192, 128, 3, 2, 0, 0, 2);

    WindowTransformImage(visibleWindow, treeImageId, 0, 192, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 64, 192, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 128, 192, 3, 2, 0, 0, 2);
    WindowTransformImage(visibleWindow, treeImageId, 192, 192, 3, 2, 0, 0, 2);


    WindowImageFromWindow(visibleWindow, betaImageId, hiddenWindow) 
-- 10,20 - positions, 3 = transparent
   -- WindowTransformImage(visibleWindow, betaImageId, 64, 128, 3, 3, 0, 0, 3);
      WindowDrawImage (visibleWindow, alphaImageId, 64, 64, 0, 0, 1)
      
      WindowImageFromWindow(visibleWindow, "alphaMaskId", alphaMaskWindow);
      WindowImageFromWindow(visibleWindow, "alphaImageId", hiddenWindow);
      WindowImageFromWindow(visibleWindow, "alphaMaskStretchedId", "alphaMaskWindowStretched")
      WindowMergeImageAlpha(visibleWindow, alphaImageId, "alphaMaskId", 128, 128, 192, 192, 0, 1, 0, 0, 0, 0);
      -- This is the one that works
      WindowMergeImageAlpha(visibleWindow, "alphaImageId", "alphaMaskStretchedId", 64, 128, 128, 192, 0, 1, 0, 0, 0, 0);





    WindowShow (visibleWindow,  true)

end -- OnPluginInstall



]]></script>



</muclient>



This was their accompanying image

https://media.discordapp.net/attachments/1007181616529035334/1037551185625886791/Screen_Shot_2022-11-02_at_7.17.43_PM.png?width=459&height=586


They told me they had to create 3 windows to make it work as intended, which is unideal, so I should probably try sticking with using WindowTransformImage and calculating the zoom levels, etc, which is fine but I'm just thinking couldn't there be an option added to WindowDrawImage or WindowDrawImageAlpha that just draws stretched and alpha, or is this insanely complicated?


btw, cave image can be found here

https://github.com/AsmodeusBrooding/Aardwolf/blob/main/GraphicalMapper/images/cave.png
Amended on Thu 03 Nov 2022 10:21 AM by Asmodeusbrooding
Australia Forum Administrator #14
Quote:


WindowMergeImageAlpha(visibleWindow, alphaImageId, "alphaMaskId", 128, 128, 192, 192, 0, 1, 0, 0, 0, 0);
      -- This is the one that works
      WindowMergeImageAlpha(visibleWindow, "alphaImageId", "alphaMaskStretchedId", 64, 128, 128, 192, 0, 1, 0, 0, 0, 0);



Once again you are confusing me. Is this intentional? You have alphaImageId in the first line and "alphaImageId" in the second line.

alphaImageId contains "chest". Your use of quotes and non-quotes for what looks like an identical variable (however with different contents) looks like a typo. Can you at least be consistent? Always use variables, and not literal quotes inside these function calls.
#15
Nick Gammon said:

Quote:


WindowMergeImageAlpha(visibleWindow, alphaImageId, "alphaMaskId", 128, 128, 192, 192, 0, 1, 0, 0, 0, 0);
      -- This is the one that works
      WindowMergeImageAlpha(visibleWindow, "alphaImageId", "alphaMaskStretchedId", 64, 128, 128, 192, 0, 1, 0, 0, 0, 0);



Once again you are confusing me. Is this intentional? You have alphaImageId in the first line and "alphaImageId" in the second line.

alphaImageId contains "chest". Your use of quotes and non-quotes for what looks like an identical variable (however with different contents) looks like a typo. Can you at least be consistent? Always use variables, and not literal quotes inside these function calls.



Hey Nick, I didn't write this, my friend did. I'm sorry if it's not ideal. I did test it and it worked, and also in my own testing you'd sometimes get errors for using variables and not strings in those functions so that's probably why it was used, but you'd know better than I would about it.

I can fix that string for you to test.
USA Global Moderator #16
Quote:
Hey Nick, I didn't write this, my friend did.

The first step then, IMO, is to read it line by line and understand what it's doing (not what someone thinks it's supposed to be doing, but what it's actually doing). Ask your friend to walk you through it if needed.

Because Nick is right. Assigning the string "chest" to a variable named alphaImageId and then also using a string "alphaImageId" looks like the product of a muddled thought process that doesn't know why a string and a variable are different. And if it's not, then an explanation for what the author is thinking would help.


With that said...

Nick, I think Asmodeusbrooding is just confused about the relationship between a transformation matrix and a target size and would benefit from a way to do the resize given a target width/height or right/bottom instead of a transformation matrix.
Amended on Sat 05 Nov 2022 08:35 PM by Fiendish
Australia Forum Administrator #17
Fiendish said:

Nick, I think Asmodeusbrooding is just confused about the relationship between a transformation matrix and a target size and would benefit from a way to do the resize given a target width/height or right/bottom instead of a transformation matrix.


OK, well, the transformation matrix really only needs two numbers to be changed. In my examples on the earlier page I used 0.5 and 0.8 (in two places, one for X and one for Y).

So, if you zoom in and the map squares are 1.5 times as large, then you need to transform the chest by 1.5 (make it 1.5x larger so it is the same size relative to the map square).

Plus, since all the squares are now 1.5 times further apart, then the X and Y offset will also need to be multiplied by 1.5, thus placing it in the correct position.

Likewise for any other zoom multiplier.
Amended on Sun 06 Nov 2022 12:22 AM by Nick Gammon
Australia Forum Administrator #18
You can convert map square sizes to a multiplication factor like this:

Say the map square are initially 40 x 60 pixels. Now you zoom in and they are 80 x 120 pixels. So, the multiplication factor is clearly 2:

80 / 40 = 2
120 / 60 = 2

So your "matrix multiplication" factor will be 2x whatever-it-was to get the chest the right size in the first place.
Australia Forum Administrator #19
See http://www.gammon.com.au/scripts/doc.php?function=WindowTransformImage



-- for scaling
WindowTransformImage (win, imageid, X_Translate, Y_Translate, miniwin.image_transparent_copy, X_Scale, 0, 0, Y_Scale) 


So you plug those figures into WindowTransformImage to get the correct translation (movement sideways) and scale (size).