Loading images to be called by the data of a value

BlitzPlus Forums/BlitzPlus Beginners Area/Loading images to be called by the data of a value

acolite246(Posted 2008) [#1]
I am trying to make a rotate image function that makes images of every single direction.

In the function, you enter what you want the image to be called and it saves that data as outimage$.

How do you make the data of the outimage variable call the sprite instead of the actual text outimage?

Thanks


David Boudreau(Posted 2008) [#2]
...I'm not exactly sure what you mean but there are some Blitz commands that are "fun, but [you should] use with caution!", while another is "quite possibly one of the most useful, yet underdocumented, confusing commands in the Blitz Basic language".

When you say "saves that data as" you might want SaveImage, but if you just want to store it somewhere (besides on the screen or buffer you're working in) you probably really want CreateImage and GrabImage instead.

In your last line, the data of an image is usually referred to in BlitzPlus by use of a "handle". A handle is kind of like a variable that you use to work with images (and sounds and other things you load into your program like images). Under the hood, it gets a number assigned to it, which is how the program knows how to get to it in memory. The particular number assigned doesn't mean anything, unless it is zero in which case there's no image loaded.

You can see if it's non-zero or not by running your program and using the BlitzPlus debugger ... press the button with the red stoplight (upper left of debugger window) while it's running, (or, to get it to stop automatically, might want to add a "Stop" line inside your program code right under the line where you load your image) and expanding the text under the "Locals" or "Globals" on the right side of the debugger.


acolite246(Posted 2008) [#3]
Here's what I want
Global outimg$
	Function rotateimg(imgfile$,outimg$)
		tempOutImgStore$=outimg$       ; loads the data of outimg$ into a temporary variable
		tempImg1 = LoadImage(imgfile$) ;makes an image out of the imgfile$ variable
		For i = 0 To 360
			tempImg2 = CopyImage(tempImg1) ;copy the image
			RotateImage(tempImg2,i) ;rotate it
			tempOutImgStore$ = tempOutImgStore$+i ;add the current direction to the tempOutImgStore variable

			tempOutImgStore$ = CopyImage(tempImg2) ;copies the rotated image to the newly defined tempOutImgStore variable 

Directly above is my problem - I need the data defined (the text of tempOutImg) to be the 'handle' for the image.
			DebugLog "Created "+tempOutImgStore$
			tempOutImgStore=outimg$
		Next
	End Function
Graphics 90,90
	
rotateimg("thisimage.png","rotatedimage")	
DrawImage rotatedimage55,45,45 ;draws the image rotatedimage55- the rotated image at 55 degrees.
Flip
WaitKey()
End



Sauer(Posted 2008) [#4]
Your best bet here would be to create a 360 element array, and store each rotation in an element of the array. I don't believe you can't convert strings to variable names, but I could be wrong. Also, in the code above, you're for loop should go from 1 to 360 or 0 to 359... angles 0 and 360 are the same.
This is what I would do:
Dim myimagerotated(360)
myimage=LoadImage("myimage.bmp")
tmpimage=CopyImage(myimage)

myimagerotated(0)=myimage
For x=1 to 359
  myimagerotated(x) =RotateImage(tmpimage,x+1)
Next

Drawimage myimagerotated(55),0,0


Thats just something I whipped up, so if there's an error I apologize. But you get the idea.


David Boudreau(Posted 2008) [#5]
Handles are numbers, not strings. The particular number is not important; it just indicates the place in memory to store the image (and the particular number is going to be different each time your run your program so it doesn't really matter to you much). The important point you want to know about a handle is that it is how you get your program to access the data. So leave the number of a handle alone, leave it "under the hood". Don't do any math with that number.

The first line in your function:
"tempOutImgStore$=outimg$ ; loads the data of outimg$ into a temporary variable"
Actually, it's not loading any data, it is just copying a string (text) from another string.
tempOutImgStore$ = tempOutImgStore$+i ;add the current direction to the tempOutImgStore variable


So, you want your tempOutImgStore$ variable to be:

rotatedimage1

...and then, ...eventually:

rotatedimage123456789[...]360

? No? (that might work in Python, not even sure about it working or not in Blitz.) It seems you are trying to add a number, i, to some text, "rotatedimage". It's probably not what you want, right? In any case, it doesn't really matter to the compiler, because you completely throw away the value you assigned to tempOutImgStore$ entirely with your very next line:

tempOutImgStore$ = CopyImage(tempImg2) ;copies the rotated image to the newly defined tempOutImgStore variable
Directly above is my problem - I need the data defined (the text of tempOutImg) to be the 'handle' for the image.



If that line of code works, it will write a very arbitrary, non-useful number to the string (text!!!) variable tempOutImgStore$. You can't really do much with that. (And, tempOutImageStore gets an entirely new value two lines later, so it's all for nothing.)

Sauer has very good advice on structuring your code and simplifying it.

Good use of DebugLog... write more of these statements earlier in your code.


Sauer(Posted 2008) [#6]
I think what he's trying to do is name the handle of his image a string generated by the function that corresponds to the angle. That way he has images with handles named image1,image2,image3 etc. and those names are generated by the function. Blitz cannot convert strings to variable names.

But this method is not only impossible with Blitz but also would be inefficient if it worked. Because think about it... you'd have 360 variables per image, which would be hard to manage anyway.

An array is your best bet here, by far. I hope that helps a bit.


acolite246(Posted 2008) [#7]
@David Boudreau
So, you want your tempOutImgStore$ variable to be:

rotatedimage1

...and then, ...eventually:

rotatedimage123456789[...]360

No? (that might work in Python, not even sure about it working or not in Blitz.) It seems you are trying to add a number, i, to some text, "rotatedimage". It's probably not what you want, right? In any case, it doesn't really matter to the compiler, because you completely throw away the value you assigned to tempOutImgStore$ entirely with your very next line:


I am, like Sauer said, trying to name the handle of the image to the string generated by the function. Also, that is why I overwrite tmpOutImgStore$. So i get
image1
then
image2
and not
 image12
.

@Sauer
angles 0 and 360 are the same.

Thought so.
But this method is not only impossible with Blitz but also would be inefficient if it worked. Because think about it... you'd have 360 variables per image, which would be hard to manage anyway.

Thanks. I could use the function to create an array like you suggested instead.

But I don't know how to do that- that's what this thread is about

...

Oh well. I guess I will just do a loop
dim myimage(360)
myimage = loadimage("image.png")
tempimage = copyimage(myimage)
for i = 0 to 359
myimagerotated(i)= rotateimage(tempImage, i)
next


But if anyone gets anywhere, I am still open to ideas!


David Boudreau(Posted 2008) [#8]
Sorry for my convoluted explanation- yes, listen to Sauer, he's a lot more concise and seems to understand what you are trying to do much more than I do obviously.

It seems you can't quite access data that way, either by assigning a variable the value of RotateImage(something,angle) nor be able to store it into an integer array. I tried but get "Illegal type conversion" error.

this works (but probably shouldn't- I don't recommend this approach):
handleMadeIntoAnumber = Int(tempImage)
myimagerotated(3) = handleMadeIntoAnumber
DrawImage myimageRotated(3),0,0 ; (45)

but I don't know about getting it back into a real handle.
Maybe something is possible with types instead?


David Boudreau(Posted 2008) [#9]
Ok how about this code-- it does not use an array, but does it do what you are trying to accomplish? It runs fast and gets you each degree (direction) of your image.

Note: Look it over first, and just know beforehand that it saves the image in each degree as a .bmp to the directory you run it from... so that's 360 files (I ran mine with a 32x32 pixel image). Also it doesn't do anything with TFormFilter etc.




Sauer(Posted 2008) [#10]
Yeah you're not going to want a game that creates 360 bmp images in a directory, that's not good and users will not like you cluttering up their hard drive. Plus, if you want to rotate more than one image, you're going to be cluttering up the works greatly. Also, you'd have to have about 720 LoadImage lines for three rotated images. Works, but not efficient. I think this is what you need:



I used arrays, and at the bottom wrote an example of how you could do it in function form. If you wanted to quicken the loading time, try rotating in increments of 2 instead of one. You're rotations will be every two degrees, but you might benefit more from the shorter load time.
I hope this helps :)


David Boudreau(Posted 2008) [#11]
A much more elegant solution, Sauer, and a lot more practical than what I offered. I'd better hold back on the bad advice. :)


Sauer(Posted 2008) [#12]
Hey bad advice is better than no advice!


acolite246(Posted 2008) [#13]
Thanks, everyone!

I guess I will have to preload handles for all of the images, but if that is the only way, it's okay!

By the way- is that code you just wrote public domain? I'm doing this for a tech fair and I need permissions!


Sauer(Posted 2008) [#14]
Oh yeah go for it, I don't care.


acolite246(Posted 2008) [#15]
Just tested that function you just wrote- nada

Here's you're error, and my error, too (This is what the thread was about)
:-)

Here's your function
	Function RotaryImage(image,index)
		For x=0 To 359
			tmpimg=CopyImage(image)
			RotateImage(tmpimg,x)
			rotatedimage(x,index)=tmpimg
		Next
	End Function

Here's your problem:
tmpimg=CopyImage(image)

I believe you meant the data stored in the variable image, not the handle 'image' itself.

If there is any way to call the data stored in the variable, I am STILL open to suggestions.

But if there is no way, I am using the multi dimensional array.

BTW in this thread I learned about multi dimensional arrays.


Sauer(Posted 2008) [#16]
I didn't receive an error at all. The function does the same thing as the For,Next loops. It uses a multi-dimensional array just as they do, but rather than have three For,Next loops like my code has, you can replace all three with:

RotateImagetoArray(redblock,0)
RotateImagetoArray(greblock,1)
RotateImagetoArray(blublock,2)



acolite246(Posted 2008) [#17]
strange!


acolite246(Posted 2008) [#18]
I have got it working, everyone! Thanks Sauer and everyone else!