File: get-data.lua

package info (click to toggle)
oocairo 1.4-1.2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 712 kB
  • sloc: ansic: 3,352; makefile: 59; sh: 15
file content (55 lines) | stat: -rw-r--r-- 2,311 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
-- This example demonstrates using the 'get_data' method on an image
-- surface to retrieve the binary data for an image.  Typically you
-- would want to do that in order to pass the data to some other library,
-- but in this case we'll write it out in a file format that Cairo doesn't
-- know about, namely PPM, which most image viewers should understand.

local Cairo = require "oocairo"

local IMAGE_WD, IMAGE_HT = 432, 234

-- Write out image data as a PPM file.  PPM is the true-colour variant of
-- the PNM class of formats.  We're using the binary version of PPM here,
-- which has three bytes per pixel, rather than three ASCII numbers per
-- pixel.  This function assumes the data is for an RGB24 or ARGB32 image.
local function write_ppm (filename, width, data, stride)
    local fh = assert(io.open(filename, "wb"))
    local height = data:len() / stride
    fh:write("P6\n", width, " ", height, "\n", "255\n")     -- header

    for y = 0, height - 1 do
        for x = 0, width - 1 do
            local offset = y * stride + x * 4
            -- Cairo stores pixel components using the native machine's
            -- byte order conventions, so to work on all platforms we need
            -- to reverse the bytes on little-endian platforms.  This is why
            -- the 'get_data' method returns an endianness indicator.
            local a, r, g, b
            if Cairo.BYTE_ORDER == "argb" then  -- big endian
                a, r, g, b = data:byte(offset + 1, offset + 4)
            else                                -- little endian
                b, g, r, a = data:byte(offset + 1, offset + 4)
            end
            fh:write(string.char(r, g, b))
        end
    end

    fh:close()
end

local surface = Cairo.image_surface_create("rgb24", IMAGE_WD, IMAGE_HT)
local cr = Cairo.context_create(surface)

-- Draw a gradient designed to include lots of different colours (mainly
-- to confirm that the three colour components come out the right way
-- round in the output file).
local grad = Cairo.pattern_create_linear(0, 0, IMAGE_WD, IMAGE_HT)
grad:add_color_stop_rgb(0,  1, 0, 0)
grad:add_color_stop_rgb(.5, 0, 1, 0)
grad:add_color_stop_rgb(1,  0, 0, 1)
cr:set_source(grad)
cr:paint()

write_ppm("get-data.ppm", surface:get_width(), surface:get_data())

-- vi:ts=4 sw=4 expandtab