In my application I am trying to save an arbitrary part of a rendered HTML canvas to an image file. In my Javascript I call ctx.getImageData(x, y, w, h)
and pass the resulting object to my macruby code (though if you know a solution in objc I am also very interested).
There I'm trying to create a NSBitmapImageRep object so that I can then save to an image format the user desires.
This is my code so far (the function gets a WebScriptObject as it's argument):
def setimagedata(d)
w = d.valueForKey("width").to_i
h = d.valueForKey("height").to_i
data = Pointer.new(:char, d.valueForKey("data").valueForKey("length").to_i)
d.valueForKey("data").valueForKey("length").to_i.times do |i|
data[i] = d.valueForKey("data").webScriptValueAtIndex(i).to_i
end
puts "data complete" # get's called
@exported_image = NSBitmapImageRep.alloc.initWithBitmapDataPlanes(data,
pixelsWide: w, pixelsHigh:h, bitsPerSample: 32,
samplesPerPixel: 4, hasAlpha: true, isPlanar: false,
colorSpaceName: NSCalibratedRGBColorSpace,
bitmapFormat: NSAlphaNonpremultipliedBitmapFormat,
bytesPerRow: 0, bitsPerPixel: 0)
puts "done" # doesn't get called
end
The code doesn't seem to get through the initWithBitmapDataPlanes
function but gives no error.
My question is: what am I doing wrong? Is this approach reasonable (if not, what would be better?).
Edit
Using Phrogz' answer below I got an intermediate solution: I use another canvas, getImageData, putImageData and toDataURL to get a data url of the region needed. In my setimagedata
I simply save the data url and my dataOfType: error:
method looks like this:
def dataOfType(type, error:outError)
workspace = NSWorkspace.sharedWorkspace
if workspace.type(type, conformsToType: "public.image")
@data_url[ /(?<=,).+/ ].unpack("m").first
end
end
The missing secrete sauce it this ugly hax:
class NSString
def writeToURL(url, options: opts, error: error)
File.open(url.path, "w") {|f| f << self }
end
end
It leverages duck typing in Cocoa and defines a selector normally on NSData to write itself to a file.
This seems to work so far and I'm happy I reached a solution. However I would still like to see a solution using NSBitmapImageRep. The next feature I'm implementing is exporting to video and I believe I will need the finer control provided by this class.