Problems with large JPG Pictures
BlitzMax Forums/BlitzMax Programming/Problems with large JPG Pictures
| ||
I try to load a 3000x2400 pixel sized JPG image, but the drawimage cannot draw it. If I use a 1900x1900 pixel image, everything is ok. If I use a 2100x1900 image, i get something on the screen, which looks like x-streched lines of the colors of the picture. It seems to me, that loading a image over 2048x2048 pixel makes problems. perhaps my grafic card is at its memory end? What can i do to load the image? Can I load it into Main RAM instead of Video RAM? How can I do this? Or is it a bug of BlitzMax? |
| ||
I'm sure the others will have better solutions, but as a stop-gap measure try splitting the image into say 4 subpieces, and drawing them together like a grid? |
| ||
no chance to do this, the program will be no game, but a picture viewer for any pictures...easy to use for the users, so i cannot have any restrictions. |
| ||
Loading as a pixmap and drawing the pixmap makes any difference? |
| ||
Perhaps you can do it behind the scenes, automatically detecting a large image and splitting it internally. The user never need know :D |
| ||
no, loading a pixmap makes no difference... decteting the size is no problem, after LOADIMAGE the size is known correct with IMAGEWIDTH(), ...but the DrawImageRect fails: Global LadeBild:Timage Datei$="test.jpg" Graphics 800,600,0,0 'LadeBild=LoadImage(Datei) LadeBild = LoadImage(LoadPixmapJPeg(Datei)) Print ImageWidth(Ladebild) + " " + ImageHeight(Ladebild) SetScale 0.2,0.2 DrawImageRect LadeBild,0,0,400,400 Print "ready" Flip WaitKey() Please tell me, how to split it. |
| ||
I meant, 'physically' splitting the one big 4Ax4B image into four new seperate images of size 1Ax1B, and then possibly discarding the old image. I'm afraid I don't know how to do this myself. |
| ||
http://www.blitzbasic.com/codearcs/codearcs.php?code=1440 Maybe this can help. |
| ||
If you are suspecting that 2048x2048 is the absolute limit then I suggest your graphics card has a `maximum texture size` of 2048. There is no way around that other than to split your image into multiple images. ALso you should be able to loadpixmap just fine and then convert it to multiple images using pixmap windows. |
| ||
Now I did it this way: 1.loading the image as a Timage 2. if it is over 2048x2048 I Convert it into a Pixmap (LockImage) 3. with two for/next-loops I read every second pixel (ReadPixel) and save it to another Pixmap with WritePixel. The new Pixmap has exact the half size of the original. For i=0 to Width-1 For j=0 to Height-1 Pixel=ReadPixel(OldImage,i*2,j*2) WritePixel NewImage,i,j,Pixel Next Next 4. At the end I overwrite the original with the smaller image. Thanks to everybody for your help! |
| ||
I don't think that will work. If you load your image as an image and not as a pixmap and then you lock the pixmap, I don't know if that downloads the image to the pixmap or whether it has retained the larger pixmap. If it doesn't retain it, you're downloading a cropped image. But I am guessing bmax keeps the pixmap even when doing a loadimage? |
| ||
2. if it is over 2048x2048 I Convert it into a Pixmap (LockImage) If the GPU doesn't support textures of that size, then it might not even get that far.Another problem - what if the user wants to view a 2048x400 image? Even if it does load, it'll take up a hell of a lot more RAM than is necessary as it could be scaled internally to 2048x2048. The only way you are going to do this reliably is by splitting up the image into sensibly sized tiles, and I'd recommend 64x64 to minimise waste. Your single, massive image basically needs to be represented as a tilemap. |
| ||
The code above was only symbolic pseudo code. In reality it works already. The loading of the images seemed to be no problem. Even big sized pictures were loaded correct. I recognized, that only the DrawImage failed. My pictureviewer only works in 1366x768. So I do not need picture sources bigger than this. If a picture comes with 3000x2000px it will have 1500x1000pix after the scaling down. This is enough for scaling it again to fit the Screen. The idea of the 64x64-tiles is of course very elegant. |
| ||
use loadAnimImage() to break the image into smaller ones. A short example here: |
| ||
For some reason, I didn't see your response before I made mine. I guess if you want to resize the image instead of tiling it, Resizepixmap might be a more elegant solution. Pixmap = LoackImage(Image) Image = LoadImage(ResizePixmap(Pixmap,Pixmap.Width/2,PixmapHeight/2)) And you're done. |
| ||
nice idea, i will test it immediately. thank you |
| ||
Even big sized pictures were loaded correct. I recognized, that only the DrawImage failed. That's because the image is really loaded as a pixmap - it doesn't become a texture until the first time you try to draw it, at which point it gets sent to the GPU. That's where the size limitations are always going to manifest themselves. use loadAnimImage() to break the image into smaller ones. LoadAnimImage relies on the image being big enough to contain the specified number of tiles of given dimensions. If the total image dimensions are not equally divisible by the tile width/height, then at best you'll get bits missing, at worst it'll fail completely. |
| ||
Each individual dimension of a texture must be a power of 2, they don't have to actually match. You are allowed 2048 x 64, 2048 x 256 etc At least that's true of OpenGL, I presume Blitz lets you do that? |