BaseBitmap.CopyPartTo() with grayscale image
oli_d last edited by oli_d
I have a problem with the method BaseBitmap.CopyPartTo()
when the basic image is in grayscale it doesn't work ! (with RGB file it works fine)
Tested with r21 and s22 on macos 10.13.6
ferdinand last edited by ferdinand
while I would not rule it out categorically that "it does not work with greyscale images", it seems very unlikely. You also forgot to tag your posting (I assume this is a Python question), to give us some example code for which the operation fails and to give us the precise symptoms of failing, i.e. the exact exception, an error code, etc.
However, this is the first thing I would check: Have you initialised your bitmap you want to copy to properly as a greyscale bitmap with a sufficient bit-depth via
oli_d last edited by oli_d
Thanks for the answer and sorry for the incomplete post ! You're absolutely right I should have put the code.
Here is an example:
import c4d def main(): fn = '/Users/donzeo/Documents/TEMP/ESRI_world_imagery-19.png' bmp = c4d.bitmaps.BaseBitmap() bmp.InitWith(fn) h,w = bmp.GetSize() mode = bmp.GetColorMode() if mode == c4d.COLORMODE_GRAY or mode == c4d.COLORMODE_AGRAY: flag = c4d.INITBITMAPFLAGS_GRAYSCALE else : flag = c4d.INITBITMAPFLAGS_NONE crop_bmp = c4d.bitmaps.BaseBitmap() if crop_bmp.Init(h/2,w/2,depth = bmp.GetBt(), flags = flag) == c4d.IMAGERESULT_OK: print bmp.CopyPartTo(crop_bmp, 10, 10, w/2, h/2) c4d.bitmaps.ShowBitmap(crop_bmp) if __name__=='__main__': main()
By the way it's the same with BaseBitmap.GetClonePart() (which is more simple !) :
import c4d def main(): fn = '/Users/donzeo/Documents/TEMP/ESRI_world_imagery-19.png' bmp = c4d.bitmaps.BaseBitmap() bmp.InitWith(fn) w,h = bmp.GetSize() part = bmp.GetClonePart(0,0,w/2,h/2) if part : c4d.bitmaps.ShowBitmap(part) else: print'error' if __name__=='__main__': main()
With rgb image there is no problem. With a grayscale image impossible to get anything. I tried psd, png, jpg ...
Am I doing something wrong?
m_adam last edited by
Hi, unfortunately as stated in the BaseBitmap Documentation some functions work only with 24bits and 32bits bitmap.
Note due to Python 3 SetPixelCnt and GetPixelCnt will be changed in R23.
And here is the previous example adapted with this new version:
""" Copyright: MAXON Computer GmbH Description: - Copies the internal data of a 32 bit per-channel image to a new one. Note: - BaseBitmap.GetClone could be used for doing the exact same purpose, bu Class/method highlighted: - BaseBitmap.SetPixelCnt() - BaseBitmap.GetPixelCnt() Compatible: - Win / Mac - R23 """ import c4d def main(): # Opens a Dialog to choose a picture file path = c4d.storage.LoadDialog(type=c4d.FILESELECTTYPE_IMAGES, title="Please Choose a 32-bit Image:") # If the user cancels, leaves if not path: return # Creates a BaseBitmap that will be used for loading the selected picture orig = c4d.bitmaps.BaseBitmap() if orig is None: raise RuntimeError("Failed to create the bitmap.") # Initializes the BaseBitmap with the selected picture if orig.InitWith(path) != c4d.IMAGERESULT_OK: raise RuntimeError("Cannot load image \"" + path + "\".") # Checks if channel depth is really 32 bit if orig.GetBt()/3 != 32: raise RuntimeError("The image \"" + path + "\" is not a 32 bit per-channel image.") # Gets selected image information width, height = orig.GetSize() bits = orig.GetBt() # Creates a BaseBitmap that will be ued for making a copy copy and initialize it copy = c4d.bitmaps.BaseBitmap() if copy is None: raise RuntimeError("Failed to create the bitmap.") copy.Init(width, height, bits) if orig.InitWith(path) != c4d.IMAGERESULT_OK: raise RuntimeError("Cannot load image \"" + path + "\".") # Calculates the number of bytes per pixel # Each pixel has RGB bits, so we need an offset of 'inc' bytes per pixel # the image has 32 bits per-channel : (32*3)/8 = 12 bytes per pixel (1 byte = 8 bits) # the image has 3 channels per pixel (RGB) : 12/3 = 4 bytes per component = 1 float inc = orig.GetBt() // 8 bytesArray = bytearray(width * height * inc) memoryView = memoryview(bytesArray) for row in range(height): memoryViewSlice = memoryView[row*(width*inc):] orig.GetPixelCnt(0, row, width, memoryViewSlice, inc, c4d.COLORMODE_RGBf, c4d.PIXELCNT_0) for row in range(height): memoryViewSlice = memoryView[row * (width * inc):] copy.SetPixelCnt(0, row, width, memoryViewSlice, inc, c4d.COLORMODE_RGBf, c4d.PIXELCNT_0) # Show original and copied image in the picture viewer c4d.bitmaps.ShowBitmap(orig) c4d.bitmaps.ShowBitmap(copy) if __name__ == '__main__': main()
oli_d last edited by
Thank you very much Maxime for the reply.
I'm looking forward to the r23 and the python 3 with a lot of impatience.