load unlimited images
BlitzMax Forums/BlitzMax Beginners Area/load unlimited images
| ||
hello everyone, I just bought blitzmax (I have little experience with it), and I have a question. I'm working on a program where the user should be able to load unlimited images. My question is how can I do that? I've tried a lot but could not find the answer. Thank You a lot! |
| ||
Load them as pixmaps using LoadPixmap.... you obviously aren't going to be able to VIEW a huge amount of images all on-screen at once, so you can simply convert them to `Images` as you need to show them. You won't be able to keep them all in video ram as Images, there just isn't enough of it (e.g. maybe only 32-64mb on many systems), so you'll have to figure out a way to spool them from pixmaps into images in a fairly smooth way - perhaps by using small `pixmap windows` from each pixmap and thus uploading only small sections of image each frame - e.g. 64x64 or 256x256, so that you are drawing `tiles` on the screen as the image scrolls or whatever. It should be fast enough to be smooth. You just wont be able to do an upload of a whole big image every frame and expect it to be smooth. By loading into pixmaps with LoadPixmap you are using main memory, so you could have a gigabyte or more available, depening on the computer. You also might consider storing the image in a compressed format in ram and only decompress as you need to view it. You could use zip or something similar. Another option is to spool images from disk as they are needed - a bit slower and more difficult to get smooth but it'd allow you to use a lot less memory. |
| ||
What do you mean by unlimited images? |
| ||
What do you mean by unlimited images? Repeat Local img:TImage = LoadImage("myimage.png") Forever heh. this was just joke but... im too thinking about unlimited images.. |
| ||
But what does that mean? Why would you do that? If you want to use the same image multiple times, you should load it as a pixmap, and then deal with that pixmap. Particularly with pngs as they are relatively slow to load, as they must be decompressed. By loading a png once into a pixmap, and then using that pixmap for all my image operations, I speeded up my loading routine by several seconds. |
| ||
@ ImaginaryHuman Thanks. I did some experimentation with LoadPixmap. it works well, but it is too slow. @ Tsaar Flavius The user can load images into the program. There should be no restriction (with images). @ Zeke if this was possible... |
| ||
The difference between an image and a pixmap, is that the image is stored in your videocards' memory, while a pixmap is in your normal computer RAM. They are slow to draw, because each time you draw a pixmap, it needs to be copied across the motherboard into video memory first. but... pixmaps are only limited by the amount of memory windows can access, which is huge in part hanks to the ability to access virtual memory if there isn't enough. By comparison, your video card needs to store everything in video memory, which tends to be significantly smaller. Other complicating factors: - Images are stored *uncompressed* in video memory, taking 4 bytes for each pixel (32 bit: 24 bits for the color, and 8 bits for alpha info) - memory allocated rounded *up* to the nearest power-of-two size. This means that an 800x600 pixel JPEG file that's 50KB on disk, all of a sudden takes up 1024 x 1024 x 4 = 4 MB of video RAM. Just because you WANT to load infinite images doesn't mean that your videocard can store an infinite amount of those 4 MB data chunks. Even completely ignoring the video memory requirements of the windows GUI itself and all it entails, you're not going to fit more than 64 of those in the video memory of a fairly typical video adapter with 256MB onboard memory. You'll either need to put up with the hassle of pixmaps, or you'll have to come up with some fancy system to load/unload your data dynamically where the user may not notice what's going on... But there are very real system limitations you're running into here. |
| ||
Very real, and very physical limitations for something like that! If you try to store an unlimited amount of images in every PC there is on the planet, you'll still eventually run out of room. What I would do is something boarding on 3D trickery when it comes to them doing large out door areas, as an example, load up, say 9 images and think of them images as a grid (With the centre on being the only visible one), if the user clicks to look right, bring the ones to the right to the centre which they see the new middle image, the old centre ones go to the left of the grid, thus, losing the original left images and fill the now vacant right hand side with new images from the harddrive! Do that for all directions, like up, down, left and right, and move, lose and replace images respectively. Obviously, you'll need a filing system in place so it knows what to drag in, but that shouldnt be too much hassle really... So, at anyone time you should only have 9 images in memory (Be in video or system), but with the potential to navigate around massive image libraries (I'll not say unlimited, because, well, theres always a limit really) Dabz |
| ||
I am aware that there is a limitation. This limitation is different for each computer. EDIT: the Programme should be able to load images until memory is full. is it also possible that all the picture pasted together into one big picture? and that the program shows a part of that big picture? @Dabhand I use blitzmax, not blitz3d. 3d is a bit difficult ;) |
| ||
I use blitzmax, not blitz3d. 3d is a bit difficult ;) Yeah, but my example on how you could handle it was based on how they manage to create massive game areas, they load bits in, the player wanders over somewhere, new bits are loaded while behind them bits of the level are dropped. This is the same, yet, instead of a entire 3D level to show, you could use the same system to display shedfuls of images without hogging the users system and crippling it! :) Dabz |
| ||
is it also possible that all the picture pasted together into one big picture? and that the program shows a part of that big picture? Have a look at GrabPixmap. you'll have to come up with some fancy system to load/unload your data dynamically where the user may not notice what's going on I thought the video card automatically swapped images between vram and ram if there is a shortage of memory. Slow of course, but shuoldn't crash the program. I think by "unlimited" he means "arbitrary amount" |
| ||
I've tried to make a load/unload system. here: ============================================== AppTitle$ = "load multi image" Graphics 600,400 'add here the lokations of the images. they must be separated by a space imageopen$ = "images/intro.png images/ge.PNG images/boss.png images/maxball.png" + " " #beg 'vieuw image names oldimageopen$ = imageopen$ y = 0 #vieu DrawText(Left(oldimageopen,Instr(oldimageopen," ")-1),0,y) oldimageopen$ = Mid(oldimageopen,Instr(oldimageopen," ")+1) y = y + 12 If Len(oldimageopen) > 1 Then Goto vieu 'select a picture If MouseHit(1) Then choose = MouseY()/12 changepic = 1 EndIf 'image If changepic = 1 Then Cls choose1 = 0 oldimageopen$ = imageopen$ If choose > 0 Then #vieua choose1 = choose1 + 1 oldimageopen$ = Mid(oldimageopen,Instr(oldimageopen," ")+1) If choose1 < choose Then Goto vieua EndIf pict = LoadPixmap(Left(oldimageopen,Instr(oldimageopen," ")-1)) DrawPixmap(pict,200,50) changepic = 0 EndIf 'exit If KeyHit(key_escape) Then End 'vieuw screen Flip Goto beg ============================================== |
| ||
Ouch... To start, and this isnt meant to be personal, so please dont take it the wrong way... But to start, you really need to look at how you are setting your apps out, thats horrible to read, check out the samples or the archives and get a bit of a handle on how everyone is programming using things like functions, loops and types. Secondly, if you want to achieve your aim, you need a bit of a plan, its okay for us to suggest stuff, and now and again people do knock out example code, by the looks of things though, someone could knock out an example and (I mean no disrespect) you wouldnt know how it works... Which is pointless really! So, what would I do if I was in your shoes... Well, I'd look at other code, read tutorials just generally play around... While I'm at it, I'd scrawl on a bit off of paper ideas that would help me get around the problem, theres been idea's here, so I would work on the best way of doing it... If I have time tomorrow (Its late here now and I'm shot) I could write something (Unless someone chips in first), but, I wouldnt explain everything, you'll have to take it as it is... Which is the worry! ;) Dabz |
| ||
Merry Christmas!!!SuperStrict 'this makes us need to state the types of variables and reduces bugs AppTitle$ = "load multi image" Graphics 600,400 'add here the locations of the images. they must be separated by a " ? " Global image_open:String = "images/intro.png ? images/ge.PNG images/boss.png ? images/maxball.png" 'the Split method will automatically split up our string for us Global images:String[] = image_open.Split(" ? ") 'this will hold the image we load Global display_image:TImage 'we will do our work within the main game loop main_loop() End Function view_image_names() Local y:Int = 0 'this will go through every image file path For Local image:String = EachIn images DrawText image, 0, y 'TextHeight can give us the height of the next no matter the font y = y + TextHeight(image_open) Next End Function Function choose_picture:Int() 'this returns the index number of the image path the user has chosen 'or it returns -1 to show nothing has been selected Local choose:Int = -1 If MouseHit(1) Then choose = MouseY()/TextHeight(image_open) End If Return choose End Function Function draw_picture() 'if a picture has been loaded, draw it If display_image DrawImage display_image, 200, 50 End If End Function Function main_loop() 'repeat until escape is pressed or the red X is clicked While (Not KeyDown(KEY_ESCAPE)) And (Not AppTerminate()) Cls 'draw the list of image paths view_image_names() 'draw the picture if one has been loaded draw_picture() Flip Delay 1 'find out what the user has chosen Local choose:Int = choose_picture() 'if choose is -1 then nothing has been chosen 'if the user clicks below the text it will give a number too big 'so check also that choose is within the number of images! If choose > -1 And choose < images.Length 'load the image from the path at this position number display_image = LoadImage(images[choose]) 'check that the image was loaded. if the image file doesn't exist for example, give an error message If Not display_image Then RuntimeError "Could not find " + images[choose] + "." End If Wend End Function |
| ||
I have a project that works with theoretically limitless numbers of images, here's a little background that may be useful. There are 3 limits to keep in mind. Displayable images (limited by the video card usually), loadable images (limited by the system's ram) and processing time (this is key to maximizing your limits). First, you can't just load things forever, you're going to hit a hardware limitation sooner rather than later. So what it comes down to is how to you make it LOOK like you're loading an infinite number of pictures. My personal approach is scaling and caching on the fly. I get a list of everything I need loaded, I then cycle through that and create batches if needed (my users actually create batches in the form of Albums) then cycle through the active batch and create thumbnails which are small so I can get tons of them in memory at once. When a user requests a full size image I display the thumbnail scaled (DrawImageRect()...) to the size of the real image (it will be blocky and blurry but it lets them know somehing is happening) then load the full image and replace the thumbnail with that ASAP. If you combine this with a caching system that retains the full size image as long as possible (until too many have been requested, however you define "too many") then you can get a fairly smooth experience. I also use threading to do the loading in the background while the rest of my program is working. If you are working on composits you could go a step further as was mentioned above and use grabimage or grabpixmap to store that, allowing you to dump the origonals... it's all very use specific, but the key is how can you make it transparent to the user that something is being removed or added to give the impression that everything is always there, rather than ACTUALLY having everything always there, which isn't possible. |
| ||
@Dabhand I have not much experience. sorry, I will do my best. @Czar Flavius great, This works great. I've compared it with my and see that I have a lot to learn. such as the locations (image_open) stride with a space, that was stupid of me. Thank you very much! The program must shows more than one picture at a time. I go there a restriction on it, maby eight photos at the time. I'm going to try to make a systeen. I want to try the same structure as that of Czar Flavius (thanks again) |
| ||
@Dabhand I have not much experience. sorry, I will do my best. Dont apologize, we all started somewhere, but, it is recommended that you have a good hunt through all the tutorials on here to get a general feel on how to get the best out of the language! :) It'll go a long way! ;) Dabz |
| ||
SuperStrict Global image_list:TList = New TList 'you can add any image variable, but for this example we use this one Local image:TImage 'load an image from wherever image = LoadImage(...) 'add it to the list! image_list.AddLast(image) 'load an image from wherever image = LoadImage(...) 'add it to the list! image_list.AddLast(image) 'load an image from wherever image = LoadImage(...) 'add it to the list! image_list.AddLast(image) Function display_all_images() Local y:Int = 0 For Local image:TImage = EachIn image_list DrawImage image, 0, y y :+ ImageWidth(image) Next End Function 'you can use this to remove an image image_list.Remove(image) 'you can use this to find out how many things are in your list image_list.Count() 'you can use this to reset your list to 0 image_list.Clear() |
| ||
Czar Flavius, wooow, it look so easy but it isn't. it work great. my problem is solved. Thank you very much. and thanks everyone for the help. |