[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
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
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.
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?
@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
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()
)