-
Notifications
You must be signed in to change notification settings - Fork 2
/
encode.jl
85 lines (64 loc) · 2.75 KB
/
encode.jl
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
"""
gif_encode(filepath::AbstractString, img::AbstractArray; num::Int = 64)
Encode the GIF colorant matrix to file.
#### Arguments
- `filepath` : Name of the file to which image is written.
- `img` : 3D GIF colorant matrix which has structure of height*width*numofimags and all the images are present as slices of the 3D matrix
- `colormapnum` : Specifies the number of colors to be used for the global colormap
### Examples
```jl
julia> using GIFImages, Downloads
julia> path = "test/data/fire.gif"
"test/data/fire.gif"
julia> img = gif_decode(path)
60×30×33 Array{RGB{N0f8},3} with eltype RGB{N0f8}
julia> gif_encode("fire.gif", img)
```
"""
function gif_encode(filepath::AbstractString, img::AbstractArray; colormapnum::Int = 256)
if(eltype(img)!= RGB{N0f8})
throw(ErrorException("gif_encode requires img to be in RGB{N0f8} colorspace currently"))
end
error1 = Cint(0)
gif_file = LibGif.EGifOpenFileName(filepath, 0, Ref(error1))
colors = []
shape = size(img)
gif_file == C_NULL && throw(ErrorException("EGifOpenFileName() failed to open the gif file: null pointer"))
(colormapnum < 1 || colormapnum > 256) && throw(BoundsError("colormapnum is out of range and needs to be in range 1-256(both inclusive)"))
(ndims(img) != 3) && throw(DimensionMismatch("Image Array needs to be in Height, Width, NumImages format."))
try
# generation of a colormap
# this changes the image directly for now
palette = kdtreequantisation!(img; numcolors=colormapnum, precheck=true)
append!(colors, palette)
mapping = Dict()
for (i, j) in enumerate(colors)
mapping[j] = UInt8(i-1)
end
# defining the global colormap
colors = map(x -> LibGif.GifColorType(x.r, x.g, x.b), colors * 255)
colormap = LibGif.GifMakeMapObject(colormapnum, colors)
# features of the file
gif_file.SWidth = shape[2]
gif_file.SHeight = shape[1]
gif_file.SColorResolution = 8
gif_file.SBackGroundColor = 0
gif_file.SColorMap = colormap
# encoding # case of 512*512
for i = 1:shape[3]
# flatten the image
img1 = vec(collect(@view(img[:, :, i])'))
pix = map(x -> mapping[x], img1)
# saving a new image in gif_file
desc = LibGif.GifImageDesc(0, 0, size(img)[2], size(img)[1], 0, C_NULL)
c = LibGif.SavedImage(desc, pointer(pix), 0, C_NULL)
LibGif.GifMakeSavedImage(gif_file, Ref(c))
end
finally
# proper file close if error happens
# writing and closing the file
if (LibGif.EGifSpew(gif_file) == LibGif.GIF_ERROR)
throw(ErrorException("Failed to write to file!"))
end
end
end