Notifications
Clear all

[Closed] How to rotate by 180° a rendered image (from vfb) ?

Hi,

i need to rotate by 180° a copy of the rendered image from the Virtual Frame Buffer (vfb).
I don’t know how to achieve this. Do i have to make a custom function that will rotate pixels (must be too long with a big image ?) or is there another way in maxscript to do this ?
I currently can’t find any help in mxs documentation.
Here is my code :

-- custom function to rotate image by pixel ?
   fn rotateBitmap180 =
   (
     --??
   )
   
   bmsize = 1024	-- currently my rendered image is 1024x1024
   bm1 = GetLastRenderedImage copy:false	-- make a copy of the previously rendered image from vfb
   bm2 = bitmap bmsize bmsize	-- create a new empty bitmap
   pasteBitmap bm1 bm2 [0,0] [0,0] type:#function function:rotateBitmap180	-- use of a custom function since 3dsmax2010 only
   display bm2	-- display rotated image

Thanks for any help

10 Replies
 lo1

I am not sure there is a way to do it with the pasteBitmap compositing function, as it does not let you choose which pixels you are getting, but a simple loop can get it done.

theBmp = getLastRenderedImage copy:off
destBmp = bitmap theBmp.width theBmp.height
w = theBmp.width
h = theBmp.height
for y = 1 to h do
(
	local row = getPixels theBmp [0, y - 1] w
	local reverseRow = for x = w to 1 by -1 collect row[x]
	setPixels destBmp [0, h - y - 1] reverseRow
)
close theBmp
free theBmp
display destBmp
2 Replies
(@denist)
Joined: 11 months ago

Posts: 0

the method doesn’t need a second bitmap. you can do it with the source. also it might be faster to use swap to make an array reverse.

 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

Is this what you had it mind? for some reason it performs a bit slower than the original (thought both are quite fast considering it is maxscript).

theBmp = getLastRenderedImage copy:off
w = theBmp.width
h = theBmp.height
halfW = w/2
halfH = h/2
for y = 1 to halfH do
(
 	local rowA = getPixels theBmp [0, y - 1] w
	local rowB = getPixels theBmp [0, h - y - 1] w
 	for x = 1 to halfW do
	(
		swap rowA[x] rowA[w-x-1]
		swap rowB[x] rowB[w-x-1]
	)
	setPixels theBmp [0, y - 1] rowB
	setPixels theBmp [0, h - y - 1] rowA
)
display theBmp

if you don’t need Alpha you can easily do it .NET… do you need to keep the alpha channel?

1 Reply
 lo1
(@lo1)
Joined: 11 months ago

Posts: 0

Keep in mind that using dotnet you’d also be clamping to 8 BPC.

@Denis : yes, i forgot to mention it but keeping alpha is needed. I’m not so familiar with .NET but if it could be faster than a function, i’ll have to give it a try.

@lo : i roughly tested your code proposition on a 256×256 bitmap and it seems to do the job very well (preserving alpha). I’ll test on a big size render to evaluate speed perfomance.

My goal is to split in 6 bitmaps the render in “box” camera type from vray (cubic map).
I can easily extract the 5 first images, but the last one is inverted (rotated by 180°), so i need to get it reversed. This way i have my 6 images to make a 360° cubic view.

thanks for your help, i can go further now

1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

if you need an alpha the using of .net bitmap methods is problematic. i would stay with the method suggested by LO.

that’s what i meant. if it’s not faster at least it has to save a lot of memory for big bitmaps.

I’ve double-checked these two flip methods and I have to say that the idea with the using swap doesn’t work. My guess was wrong. so the best performance shows the LO’s original method that after a little clean-up looks:


fn flipBitmap theBmp =
(
	w = theBmp.width
	h = theBmp.height
	destBmp = bitmap w h
	for y=0 to h-1 do
	(
		row = getPixels theBmp [0, y] w
		row = for x = w to 1 by -1 collect row[x]
		setPixels destBmp [0, h - y - 1] row
	)
	destBmp
)


here is dotnet version… it works 5 times faster and doesn’t use any memory but has some known limitation:


fn dotnetFlipBitmap theBmp =
(
	setclipboardBitmap theBmp 
	clipboard = dotnetclass "Clipboard"
	b = clipboard.GetImage()
	b.RotateFlip (dotnetclass "System.Drawing.RotateFlipType").RotateNoneFlipXY
	clipboard.SetImage b
	getclipboardBitmap() 
)