D bindings to the GraphicsMagick library.
Revisión | dd4985919d78d0cf37ab4b2ab99bb2ecec6aec15 (tree) |
---|---|
Tiempo | 2023-07-22 15:10:38 |
Autor | Mio <stigma@disr...> |
Commiter | Mio |
[examples] Add extract_gif example
@@ -13,13 +13,31 @@ be suffixed with the compiler identifier (_dmd, _gdc, _ldc). | ||
13 | 13 | Descriptions |
14 | 14 | ------------ |
15 | 15 | |
16 | -* convert.d: An example which takes an input file, applies some | |
17 | - modifications, and writes it to a specified output file. | |
18 | - ./convert <infile> <outfile> | |
16 | +* convert.d: An example which takes an input file, applies some | |
17 | + modifications, and writes it to a specified output file. | |
18 | + ./convert <infile> <outfile> | |
19 | 19 | |
20 | -* make_gif.d: A custom example which demonstrates how you can make a GIF | |
21 | - from multiple input images. | |
22 | - ./make_gif <infile1> <infile2> [...<infileN>] <outfile> | |
20 | +* extract_gif.d: A custom example that takes an input GIF image and breaks | |
21 | + it up in to separate frames and writes each frame in to | |
22 | + a sub-directory based off of the input filename. Delay | |
23 | + and DisposeType information is displayed where valid to | |
24 | + assist with re-creating the GIF. | |
25 | + ./extract_gif <infile.GIF> | |
23 | 26 | |
24 | -* ping.d: A custom example which shows how to read information about an | |
25 | - image using the D Wrapper of the C library. ./ping <infile> | |
27 | +* make_gif.d: A custom example which demonstrates how you can make a GIF | |
28 | + from multiple input images. | |
29 | + ./make_gif <infile1> <infile2> [...<infileN>] <outfile> | |
30 | + | |
31 | +* ping.d: A custom example which shows how to read information about an | |
32 | + image using the D Wrapper of the C library. ./ping <infile> | |
33 | + | |
34 | + | |
35 | +Supporting Files | |
36 | +---------------- | |
37 | + | |
38 | +* soyosoyo_a_2x5_10.gif: The GIF file that is used for testing extract_gif and | |
39 | + make_gif. The delay between frames is 10 hundredths | |
40 | + of a second, and the dispose type is background. If | |
41 | + you want to try your own GIF, you'll probably have to | |
42 | + edit make_gif.d. | |
43 | + SOURCE: https://piapro.jp/t/MCZP |
@@ -0,0 +1,105 @@ | ||
1 | +/* | |
2 | + File: examples/make_gif.d | |
3 | + Contains: An example program which takes an input GIF and breaks it | |
4 | + in to separate images. | |
5 | + Copyright: (C) 2023 Mio | |
6 | + | |
7 | + Permission is hereby granted, free of charge, to any person obtaining a copy | |
8 | + of this software and associated documentation files (the "Software"), to deal | |
9 | + in the Software without restriction, including without limitation the rights | |
10 | + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
11 | + copies of the Software, and to permit persons to whom the Software is | |
12 | + furnished to do so, subject to the following conditions: | |
13 | + | |
14 | + The above copyright notice and this permission notice shall be included in all | |
15 | + copies or substantial portions of the Software. | |
16 | + | |
17 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
18 | + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
19 | + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
20 | + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
21 | + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
22 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
23 | + SOFTWARE. | |
24 | +*/ | |
25 | +module app; | |
26 | + | |
27 | +import std.file : exists, mkdir; | |
28 | +import std.format : format; | |
29 | +import std.path : baseName, buildPath, dirSeparator, stripExtension; | |
30 | +import std.stdio : stderr, writefln; | |
31 | + | |
32 | +import magickd; | |
33 | + | |
34 | +void extract(ref MagickWand wand, string dirname) | |
35 | +{ | |
36 | + string frameFilename = format!"%s_%05d.gif"(dirname, wand.getImageIndex()); | |
37 | + writefln("%s:", frameFilename); | |
38 | + if (wand.imageDispose < DisposeType.max && wand.imageDispose >= DisposeType.min) { | |
39 | + writefln(" Dispose: %s", wand.imageDispose); | |
40 | + } else { | |
41 | + writefln(" Dispose:"); | |
42 | + } | |
43 | + writefln(" Delay: %s hundredths of a second", wand.delay); | |
44 | + wand.writeImage(buildPath(dirname, frameFilename)); | |
45 | +} | |
46 | + | |
47 | +void extractForward(ref MagickWand wand, string dirname) | |
48 | +{ | |
49 | + stderr.writefln("(NOTE: Images being written forwards)."); | |
50 | + | |
51 | + // Extract first image so we don't break the loop early. | |
52 | + extract(wand, dirname); | |
53 | + while (wand.hasNextImage()) { | |
54 | + wand.nextImage(); | |
55 | + extract(wand, dirname); | |
56 | + } | |
57 | +} | |
58 | + | |
59 | +void extractReverse(ref MagickWand wand, string dirname) | |
60 | +{ | |
61 | + stderr.writefln("(NOTE: Images being written in reverse)."); | |
62 | + | |
63 | + // Extract first image so we don't break the loop early. | |
64 | + extract(wand, dirname); | |
65 | + while (wand.hasPreviousImage()) { | |
66 | + wand.previousImage(); | |
67 | + extract(wand, dirname); | |
68 | + } | |
69 | +} | |
70 | + | |
71 | +int main(string[] args) | |
72 | +{ | |
73 | + if (args.length != 2) { | |
74 | + stderr.writefln("usage: %s <input.gif>", args[0]); | |
75 | + return 1; | |
76 | + } | |
77 | + | |
78 | + initializeMagick(null); | |
79 | + | |
80 | + MagickWand gif = MagickWand.create(); | |
81 | + gif.readImage(args[1]); | |
82 | + | |
83 | + string filename = baseName(args[1]).stripExtension(); | |
84 | + if (!exists(filename)) { | |
85 | + mkdir(filename); | |
86 | + } | |
87 | + | |
88 | + if (gif.format != "GIF") { | |
89 | + stderr.writefln("ERR: Input image format not GIF: %s", gif.format); | |
90 | + return 1; | |
91 | + } | |
92 | + | |
93 | + writefln("Extracting %d images to .%s%s%s", gif.getNumberImages(), | |
94 | + dirSeparator, filename, dirSeparator); | |
95 | + | |
96 | + if (gif.hasPreviousImage()) { | |
97 | + extractReverse(gif, filename); | |
98 | + } else if (gif.hasNextImage()) { | |
99 | + extractForward(gif, filename); | |
100 | + } else { | |
101 | + extract(gif, filename); | |
102 | + } | |
103 | + | |
104 | + return 0; | |
105 | +} |