I am attempting to save the currently visible
ui.Viewto a JPEG image file however when it saves it always returns a blank white JPEG image. My current code.
def captureNow(sender): print "Capture Screen" layer = v.layer() UIGraphicsBeginImageContext(layer.bounds().size) layer.renderInContext_(UIGraphicsGetCurrentContext()) # v.drawViewHierarchyInRect_afterScreenUpdates_(v.bounds(), True) image = ObjCInstance(UIGraphicsGetImageFromCurrentImageContext()) UIGraphicsEndImageContext() vt = ui.View() vt.width = 800 vt.height = 600 UIImageView = ObjCClass('UIImageView') iview = UIImageView.alloc().initWithImage_(image) iview.setFrame_(ObjCInstance(vt).bounds()) print iview ObjCInstance(vt).addSubview_(iview) vt.present('sheet') UIImageJPEGRepresentation(image, 1.0).writeToFile_atomically_('test.jpg', True)
def UIImageJPEGRepresentation(image, compressionQuality): func = c.UIImageJPEGRepresentation func.argtypes = [ctypes.c_void_p, ctypes.c_float] func.restype = ctypes.c_void_p return ObjCInstance(func(image.ptr, compressionQuality))
I have attempted to check to see if it is the result of saving it from a UIImage object to NSData and then to a file by trying to show the UIImage in a UIImageView however I cannot get that to work.
omz last edited by omz
That (mostly) works for me. Maybe your view doesn't have actual content?
drawViewHierarchyInRect:etc. only work within the view hierarchy, i.e. it wouldn't render any views that are on top of (but not children) of the view you're rendering, even though they appear inside the view on screen...
ui.Viewmodule already has a
draw_snapshotmethod that essentially does the same thing (edit: just noticed this is undocumented)
@omz, thank you for the information however after a little bit of research I think it has something to do with the
AVCaptureVideoPreviewLayerlayer that I am trying to save.
omz last edited by
Ah, yeah, those are a bit special... I think it should be possible to get a video frame from the camera some other way, but I haven't yet had the time to look into it. The low-level camera APIs are somewhat difficult to work with via ctypes...
This post is deleted!
I have been able to create a delegate class to get a
sampleImageBufferI am now working on getting the image from that. I think it will work. (Trying to make a CGContext at the moment).
It was going so well until I got to creating a CGBitmapContext
def CGBitmapContextCreate(baseAddress, width, height, param_0, bytesPerRow, colorSpace, flags): func = c.CGBitmapContextCreate func.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_void_p, ctypes.c_int32] func.restype = ctypes.c_void_p print ObjCInstance(colorSpace).ptr result = func(baseAddress, width, height, param_0, bytesPerRow, ObjCInstance(colorSpace).ptr, flags) print result if result is not None: return result else: raise RuntimeError('Failed to create context')
Will always fail. Is there some way that I can get an error log on why this is failing other than me throwing a RuntimeError?
I solved the issue, with information from here however I would still like to know if I can get detailed log information.
JonB last edited by
did you check all of your inputs?
colorspace/bytesperrow seems to be a common mistake.
Cethric last edited by Cethric
Ok I have got it to render the image to a file however the render image is still incorrect.
Script available here
It now renders in black and white.