Image scaling
BlitzMax Forums/BlitzMax Beginners Area/Image scaling
| ||
I'm trying to write a method that scales an image file. As SetScale gives a bit of a blurry and anti-aliased effect and the images I'm trying to scale have very few pixels I think it would be better to write a custom method. What I want is that every pixel in the image gets multiplied by a given amount; so when you're scaling an image by the factor 4, every pixel in the image will turn into a 4x4 rectangle. I hope this does not sound to confusing. I think the function I have works, but that I'm doing something wrong with the reading/writing/creating of pixmaps/images. I don't have much experience with the modification of pixmaps, so could someone please have a glance at my method and look what is wrong? Method scaleImage(_im:TImage, _sx:Int, _sy:Int) Local im:TImage, pm:TPixmap, pm2:TPixmap, w:Int, h:Int Local x:Int, y:Int, x2:Int, y2:Int, pix:Int w = _im.width h = _im.height im = TImage.Create(w, h, 1, 0, 0, 0, 0) pm2 = CreatePixmap(w * _sx, h * _sy, PF_RGB888) DrawImage(_im, 0, 0) pm = GrabPixmap(0, 0, w, h);Cls For x = 0 Until w For y = 0 Until h For x2 = 0 Until _sx For y2 = 0 Until _sy WritePixel(pm2, pm.ReadPixel(x,y), x * _sx + x2, y * _sy + y2) Next Next Next Next im.pixmaps[0] = pm2 DrawImage(im,0,0);Flip;WaitKey() End Method I'm getting the error: "Unhandled exception: Pixmap coordinates out of bounds" (highlighting the WritePixel line). |
| ||
You need For x = 0 To w - 1, and For y = 0 to h - 1. |
| ||
Isn't that the same as For x = 0 Until w? It didn't work, I think there is something wrong with the pixmaps but I really can't figure out what. When I change "WritePixel(pm2, pm.ReadPixel(x,y), x * _sx + x2, y * _sy + y2)" to "WritePixel(pm2, pm.ReadPixel(1,1), 1, 1)" I'm getting the same error. When I draw pm after grabbing it from screen it draws the image correct, so there's probably something wrong with pm2. Thanks for the help Gfk, any idea what else it can be? |
| ||
You need For x = 0 To w - 1, and For y = 0 to h - 1. There is nothing wrong with the Until Conard has used - it does the same thing. You are going to kick yourself, but I think the actual problem you have is simply from you writing the parameters in the wrong order for WritePixel (from the docs): ;-) WritePixel( pixmap:TPixmap,x,y,argb ) You have put the pixel before the coordinates in your line, therefore, it should be changed to: WritePixel(pm2, x * _sx + x2, y * _sy + y2, pm.ReadPixel(x,y)) |
| ||
Thanks a lot, it works perfectly now! Yes, I do feel stupid ^^. |
| ||
I've got some more problems. In my code I'm turning the original image into a Pixmap by drawing the image and then using GrabPixmap. For this however, I will have to clear the screen so all the things that are allready there won't come on the image. This means I will lose what ever there was on the screen before the scale... Ofcourse I could save the entire screen in an image and then draw it again at the end of the method; but is it also possible to turn an image directly into a pixmap? Also, the scaled image doesn't get 'maskblended' anymore, it has a black background when I draw it (blend is set to MASKBLEND, image flag also contains MASKEDIMAGE, maskcolor is set to (0, 0, 0)). Anyone know what the problem might be? |
| ||
As SetScale gives a bit of a blurry and anti-aliased effect and the images I'm trying to scale have very few pixels I think it would be better to write a custom method. I believe AutoImageFlags defaults to "MASKEDIMAGE | FILTEREDIMAGE | MIPMAPPEDIMAGE". Take out the FILTEREDIMAGE and I see if it gets rid of the anti-aliasing. AutoImageFlags MASKEDIMAGE | MIPMAPPEDIMAGE |
| ||
Conard, correct me if I am wrong but try using the command AutoImageFlags 0 at the beginning of your program and then try scaling your image up. It will then retain its full pixel quality. If this s not what you are aiming for then please ignore me ;) Jason. |
| ||
Guys. If an image is 100 pixels wide, then you read the pixels from 0-99 - not 0-100. That's what I was getting at - you clearly just didn't read it properly. Whether you use To or Until is personal preference. |
| ||
Nope, Until runs 1 less than To. |
| ||
@Vilu and QuickSilva: Editing the image flags indeed does the job :). Just out of curiosity, is it possible to turn an image into a pixmap? Thanks for the help all. |
| ||
not directly but you can get the pixmap from the image with lockimage. note that whatever you do to the pixmap will affect the image. |
| ||
See the thread here: http://www.blitzbasic.com/Community/posts.php?topic=73042#816959 See the post(s) by me, I submitted code for doing simultaneous zooming and rotating of an image. It doesn't do any kind of filtering/smoothing but you can zoom in or out properly and rotate at the same time. |