[Closed] Copy red channel to another bitmap
Other then using get and set pixels which is really slow what method do you think is out there that I could use to get the red channel of one bitmap and paste it into another?
What about the new Color Correct (use this to extract the needed channels) + Composite Map (use this to combine the different maps R+G+B maps should generate what you need)?
-Eric
I’m thinking this is faster… python with the pil module…
SplitRGB.py
import Image
import sys
im = Image.open(sys.argv[1])
(r,g,b) = im.split()
r.save(sys.argv[1])
Save image to temp, doscommand line this py with the filename, reload the image.
You could make it pretty with a second argument to select r,g, or b…
Edit: just saw your post… yeah… this isn’t gonna work for you… time to bust out the C skills and write a function…
I would think there’s something in .net to do this… Might take you longer to find it than write your own…
So know way with dotNet? Been digging at that and not comming up with anything.
I can’t image it’s faster… but you can try it…
Example of pixel handling in dotnet…
http://msdn.microsoft.com/en-us/library/system.drawing.image.pixelformat.aspx
Thanks, I know of that one as well but I wouldn’t think that it is faster either, I haven’t tried it how ever. I’ll keep digging. Has to be some way to get the red channel.
Can u use the renderer? Maybe a quick scan line render. Plane, Camera, standard mat 100% lum with colormapping enabled and knock out the blue and green with the colormapping. A real hacky way to get there and it’ll degrade the image too…
how big are the images you are processing paul? how quick do you need it to be? keith’s link is a good snippet of code for this. It might be possible to do it quicker with some custom image handling classes using the lockbits method, but you would be burdened with an assembly to load in.
Try this:
--******************************************************************************
--*
--* extractBitmapChannel
--* by Ofer Zelichover (c)
--* Started: 2008/08/20
--* http://www.oferz.com ; maxscripts@oferz.com
--*
--******************************************************************************
(
-- This function uses the dotNet graphics object with color matrix to extract
-- a specific channel from a bitmap.
-- Valid chan values: #Red, #Green, #Blue, #R, #G, #B
fn extractBitmapChannel bm chan =
(
-- Validate chan value:
chan = (chan as string) as name
local fullChanNames = #(#Red, #Green, #Blue)
local shortChanNames = #(#R, #G, #B)
local n = findItem fullChanNames chan
if n > 0 then
chan = shortChanNames[n]
if findItem shortChanNames chan == 0 then
return undefined
-- Copy the bitmap to the clipboard to pass it to dotNet
setClipboardBitmap bm
-- Create a dotNet clipboard object.
local clipboardObj = dotNetClass "System.Windows.Forms.Clipboard"
-- Get the image from the clipboard into a dotNet image object.
local imgObj = clipboardObj.GetImage()
-- Create a dotNet colorMatrix object.
local colorMatArray = #( \
#(if chan == #R then 1 else 0, 0, 0, 0, 0), \
#(0, if chan == #G then 1 else 0, 0, 0, 0), \
#(0, 0, if chan == #B then 1 else 0, 0, 0), \
#(0, 0, 0, 1, 0), \
#(0, 0, 0, 0, 1)
)
local colorMatrixObj = dotNetObject "System.Drawing.Imaging.ColorMatrix" colorMatArray
-- Create a dotNet ImageAttributes object to assign the color matrix to the image.
local imageAttrsObj = dotNetObject "System.Drawing.Imaging.ImageAttributes"
imageAttrsObj.SetColorMatrix colorMatrixObj (dotNetClass "System.Drawing.Imaging.ColorMatrixFlag").Default (dotNetClass "System.Drawing.Imaging.ColorAdjustType").Default
-- Create a dotNet graphics object. This will be used to render the image using the color matrix.
local graphicsObj = (dotNetClass "System.Drawing.Graphics").FromImage(imgObj)
-- Render the image using the color matrix:
local rect = dotNetObject "System.Drawing.Rectangle" 0 0 imgObj.Width imgObj.Height
local graphicsUnit = (dotNetClass "System.Drawing.GraphicsUnit").Pixel
graphicsObj.DrawImage imgObj rect 0 0 imgObj.Width imgObj.Height graphicsUnit imageAttrsObj
-- copy the rendered image into the clipboard.
clipboardObj.setImage(imgObj)
-- Get the image from the clipboard back into maxscript
local newBm = getClipboardBitmap()
--Clean up
clipboardObj = undefined
graphicsObj.Dispose(); graphicsObj = undefined
rect = undefined
graphicsUnit = undefined
imgObj.Dispose(); imgObj = undefined
imageAttrsObj.Dispose(); imageAttrsObj = undefined
colorMatrixObj = undefined
-- You may wish to comment out the GC command if it's too slow.
gc light:true
-- Return the new bitmap
newBM
)
-- Sample Use:
local tex = Dent color1:red color2:blue size:5
local bm = bitmap 200 200
renderMap tex into:bm
display(extractBitmapChannel bm #Red)
)
Cheers,
o
Yes this is something that I didn’t want to do as I knew it would be slower to read and write.
Thanks for the reply. That’s interesting. I’m still trying to get my head around where things actully reside, when they are being chucked around between a script and .net.