[英]How to create an image from canvas data?
在我的应用程序中,我试图将呈现的HTML画布的任意部分保存到图像文件中。 在我的Javascript中,我称之为ctx. getImageData (x, y, w, h)
ctx. getImageData (x, y, w, h)
并将生成的对象传递给我的macruby代码(尽管如果你知道objc中的解决方案我也很感兴趣)。
在那里,我正在尝试创建一个NSBitmapImageRep对象,以便我可以保存为用户所需的图像格式。
到目前为止这是我的代码(该函数获取WebScriptObject作为其参数):
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
代码似乎没有通过initWithBitmapDataPlanes
函数,但没有给出错误。
我的问题是:我做错了什么? 这种方法是否合理(如果没有,哪种更好?)。
使用下面的Phrogz答案,我得到了一个中间解决方案:我使用另一个画布,getImageData,putImageData和toDataURL来获取所需区域的数据网址。 在我的setimagedata
我只需保存数据url和我的dataOfType: error:
方法如下所示:
def dataOfType(type, error:outError)
workspace = NSWorkspace.sharedWorkspace
if workspace.type(type, conformsToType: "public.image")
@data_url[ /(?<=,).+/ ].unpack("m").first
end
end
这个丑陋的hax丢失的秘密酱:
class NSString
def writeToURL(url, options: opts, error: error)
File.open(url.path, "w") {|f| f << self }
end
end
它利用Cocoa中的duck类型,并在NSData上定义一个选择器,将自己写入文件。
这似乎到目前为止工作,我很高兴我达成了解决方案。 但是我仍然希望看到使用NSBitmapImageRep的解决方案。 我正在实现的下一个功能是导出到视频,我相信我需要这个类提供更好的控制。
我建议使用Canvas.toDataURL ,而不是使用getImageData
。 这将为您提供恰好是base64编码的二进制PNG(或JPEG)。 对base64进行解码,您将拥有一个可以为用户保存的文件,或者可以转换为另一种格式的进程。
编辑 :我最初删除了我的答案,因为我意识到你想要序列化画布的子区域。 然后我意识到,如果这有助于你可以改为:
要解码base64数据,可以使用base64
ruby库的decode64方法。 请注意,此方法的实现非常简单,您可以将其内联:
def decode64(str)
str.unpack("m").first
end
编辑2 :例如,给定放置在Ruby字符串中的toDataURL
调用的结果,只需:
require 'base64'
data_only = data_url[ /(?<=,).+/ ] # Find everything after the first comma
File.open( 'foo.png', 'w' ){ |f| f << Base64.decode64( data_only ) }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.