koreader/koreader-base

add functions to save images to file.

pazos opened this issue · 8 comments

pazos commented

from koreader/koreader#6635 (comment)

like bb:writePNG, but for jpg and bmp formats too.

bb:writePNG is intended to write whatever is in the memory buffer, but can be changed to write a different buffer instead (like in https://www.mobileread.com/forums/showpost.php?p=4029556&postcount=34)

But we might want to have a general function to write images, which does a few additional steps:

  1. check if the buffer fits in the framebuffer. If not scale to fit.
  2. check if the buffer has the same screen ratio than the framebuffer. If not then write the image centered with BLACK/WHITE filling the empty space.
  3. make some options toggable, like choosing fill color or when is neccesary to scale the image or is ok to write it at current resolution, even if that doesn't match FB size.

Since I am a beginner in Lua, I need help saving the image as jpg.
I am not sure if writing the jpg-buffer into the file is correct, at least the generated jpg-file is wrong.
I use the following code:

local dummy = require("ffi/turbojpeg_h")
local turbojpeg
if ffi.os == "Windows" then
turbojpeg = ffi.load("libs/libturbojpeg.dll")
giflib = ffi.load("libs/libgif-7.dll")
elseif ffi.os == "OSX" then
turbojpeg = ffi.load("libs/libturbojpeg.dylib")
giflib = ffi.load("libs/libgif.7.dylib")
else
turbojpeg = ffi.load("libs/libturbojpeg.so")
giflib = ffi.load("libs/libgif.so.7")
end

function BBRGB24_mt.__index:writeJPG(filename, bgr)

local w, h = self:getWidth(), self:getHeight()
-- Create a copy of the input BB, but with no padding and no soft rotation.
local bbdump = BB.new(w, h, TYPE_BBRGB24, nil, w * 3, w)
bbdump:blitFrom(self)

local handle = turbojpeg.tjInitCompress()
assert(handle, "no TurboJPEG API compressor handle")

local format = turbojpeg.TJPF_RGB
if bgr then
    format = turbojpeg.TJPF_BGR
end

local bufsize = turbojpeg.tjBufSize(w, h, turbojpeg.TJSAMP_411)
local buf = turbojpeg.tjAlloc(bufsize)

local width = ffi.new("int[1]")
local height = ffi.new("int[1]")
local jpgsize = ffi.new("unsigned long[1]")
width[0] = w
height[0] = h

local result = turbojpeg.tjCompress2(handle, ffi.cast("const unsigned char*", bbdump.data), width[0], width[0] * 3, height[0], format, ffi.cast("unsigned char**", buf), ffi.cast("unsigned long*", jpgsize), turbojpeg.TJSAMP_411, 100, 0);

if result == 0 then
    local fh = io.open(filename, "wb")
    assert(fh, "couldn't open JPG file")

    fh:write(ffi.string(buf, jpgsize[0]))
    fh:close()
end

turbojpeg.tjFree(buf)
turbojpeg.tjDestroy(handle)
bbdump:free()

end

I think this issue can be closed, because @zwim has written a plugin for this.

Well, we don't have JPG yet, should we want it. :-) BMP's in #1233

I think jpg is not needed because on the tolinos the trick of renaming from png to jpg works.

@elvvis Well, that's only on tolinos, there are still Kobo, Kindles, and other android devices :)

@Galunid: This issue was originally intended to provide a way to save the book cover and use it as a system screensaver on devices that do not run the KOReader screensaver.

zwim commented

I'd say not to close it, as jpg should come, too.

zwim commented

I think it can be closed with #1241 merged.