簡體   English   中英

如何從畫布數據創建圖像?

[英]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進行解碼,您將擁有一個可以為用戶保存的文件,或者可以轉換為另一種格式的進程。

編輯 :我最初刪除了我的答案,因為我意識到你想要序列化畫布的子區域。 然后我意識到,如果這有助於你可以改為:

  1. 創建一個子區域大小的新畫布。
  2. 使用context.drawImage()將子區域從原始畫布復制到新畫布。
  3. 在新畫布上調用Canvas.toDataURL以獲取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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM