image dimensions

hello!

right now, i have a formula to calc the the correct scale of the image in panda.
e.g. i have an image “bla.png” that is [color=red]100x[color=red]36 px.

image = loader.loadTexture(‘bla.png’)
isizeX = ([color=red]100.0*(8.0/3.0)/2)/1024 #1024 is the width of my panda win
isizeZ = [color=red]36.0/768 #768 is the height of my panda win
pic = OnscreenImage(image, scale=(isizeX,1,isizeZ))

this gives me the correct scale of the loaded image in the panda render window.

is there a way to get the width and height of the original image?

something like that would be fine:
isizeX = ([color=red]getWidth(bla.png)*(8.0/3.0)/2)/1024
isizeZ = [color=red]getHeight(bla.png)/768

or do i always have to manually set it ?

greets

You can use getXSize and getYSize on the texture, like this:

isizeX = (pic.getTexture().getXSize()*(8.0/3.0)/2.0)/1024.0
isizeZ = pic.getTexture().getYSize()/768.0

hmmm that doesn’t …

i have:
buttonImg = loader.loadTexture(‘buttonRect.png’)
sizeX = buttonImg.getTexture().getXSize()

which gives me the error:
‘libpanda.Texture’ object has no attribute ‘getTexture’

any ideas?

edit: buttonImg.getXSize() gives me 512 for a picture with 800 px width.
but i need the pixel value of the original picture to calc the pandascale for that img

by the way…
is there no built-in function that calculates these values depending on the screensize?

you should not be using 100x36 in the first place see ( panda3d.org/manual/index.php/Choos … xture_Size )

if you did get the width and height it would most likely be incorrect because panda would auto scale it to 128x64 for instance - or at least i would hope so!

if you look at the reference panda3d.org/apiref.php?page=Texture

image = loader.loadTexture('bla.png') 
image.getXSize()
image.getYSize()

Oh, yeah, sorry.
buttonImg.getXSize() is the correct one.
It returns 512 because 800 is rounded to a power of two I think. Please read the manual page that Treeform referred to and choose powers of two for your texture size.

You can use PNMImage to get the size of the original image before Panda rescales it to a power of 2. But if your goal is to make a card of the appropriate size to display a 2-d image in its original scale and aspect ratio, a much easier way to do this is to use egg-texture-cards ahead of time.

egg-texture-cards -o bla.egg -p 384,384 bla.png

Then, you can just load bla.egg in-game and attach it to aspect2d, and you’re golden:

bla = loader.loadModel('bla.egg')
bla.reparentTo(aspect2d)

David

yep, thanks!
thats exactly what i need, because i create extended DirectButtons with images given from database.
i don’t want to create eggs for all these pngs. this would be a lot of work…

so just creating a PNMImage with the png-file, getting its X and Z values, calculate the correct scale for my DirectButton-OnscreenImage, and then destroy (clear()) the PNMImage again is the best way for me, i think.

thanks again!

Note that you can also do:

egg-texture-cards -o images.egg -p 384,384 *.png

And then:

images = loader.loadModel('images.egg')
bla = DirectButton(geom = images.find('**/bla'), pos = (-0.5, 0, 0))
foo = DirectButton(geom = images.find('**/foo'), pos = (0.5, 0, 0))

To create two buttons, one from bla.png and foo.png. In fact, you can have any number of textures combined into one egg file in this way.

This is the purpose for which egg-texture-cards was designed. There are other real advantages to using egg-texture-cards to load textures via an egg file, instead of loading them directly via loadTexture(); the biggest advantage is that it makes it possible to (eventually) optimize your texture usage using egg-palettize, which can automatically mosaic multiple small textures onto one large texture, for optimal rendering performance (and doing this also allows you to have non-power-two textures without imposing a render performance hit or a load-time hit).

Of course, at the end of the day you should use whichever interface seems easiest to you. That’s why these multiple interfaces exist. Loading the texture directly is straightforward and simple. Come to that, if you didn’t want to mess around with PNMImage, and you were confident that your graphics card can render non-power-two textures, you could just put:

textures-power-2 none

in your Config.prc file, and then your original approach of using tex.getXSize() and tex.getYSize() would work. But I don’t recommend this approach, unless you have no plans of running your application on any other computer than your own.

David

thank you for the infos!
a question concerning to these matters:

i have a mainmenu, a searchmenu, and other menus…

  1. if i switch to the searchmenu: would i then want to load one big eggfile with all the images in it before doing a search?
    if the search returns lets say 10 results, isn’t an egg with 500 images the wrong way, because i just need 10 images of that egg? better load the 10 images one at a time for every button i create then?

  2. doesn’t it cost a lot of memory and/or performance, if i load that big egg-file?

  3. lets assume the search never returns more than about 20 searchresults.
    wouldn’t it be less expensive to just do a loadTexture(image) for all 20 results?

  4. would you in either case load one “big” eggfile with all images in it?

  5. maybe the egg doesn’t really cost anything? only the elements created with the images (e.g. load eggfile - create button with OnscreenImage - now the image allocates memory) ?

  6. final question: are there some articles about egg, texture, image costs, memory, performance…?

greets

Well, are you going to display the other menus eventually anyway? If you are, you’re going to have to load those images eventually, and it might be better to load them all at once, at application startup, instead of as-you-go. But if it’s likely that you will never load more than a small subset of the images, you have three choices: (1) load the big egg file anyway, and see what the hit is–it might not be too bad; (2) break up the images into related subsets, for instance, an egg file for each of the mainmenu, searchmenu, and each of your other menus; or (3) put the following in your Config.prc file:

preload-textures 0

Which tells Panda not to load any of the texture images from disk until they are actually rendered, which makes it basically free to load the big egg file.

As to documents about all this, well, there is the manual, and there is the forums. Topics like this do come up from time to time, so you can try browsing through the old forum posts.

David