1#!/usr/local/bin/python
2#coding: utf-8
3
4#
5# This program is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation; either version 3 of the License, or
8# (at your option) any later version.
9#
10# This program is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with this program.  If not, see <https://www.gnu.org/licenses/>.
17
18"""
19Exports the image histogram to a text file,
20so that it can be used by other programs
21and loaded into spreadsheets.
22
23The resulting file is a CSV file (Comma Separated
24Values), which can be imported
25directly in most spreadsheet programs.
26
27The first two collums are the bucket boundaries,
28followed by the selected columns. The histogram
29refers to the selected image area, and
30can use either Sample Average data or data
31from the current drawable only.;
32
33The output is in "weighted pixels" - meaning
34all fully transparent pixels are not counted.
35
36Check the gimp-histogram call
37"""
38
39
40from gimpfu import *
41import csv
42import gettext
43
44
45gettext.install("gimp20-python", gimp.locale_directory, unicode=True)
46
47def histogram_export(img, drw, filename,
48                     bucket_size, sample_average, output_format):
49    if sample_average:
50        new_img = pdb.gimp_image_duplicate(img)
51        drw = pdb.gimp_image_merge_visible_layers(new_img, CLIP_TO_IMAGE)
52    # TODO: grey images, alpha and non alpha images.
53    channels_txt = ["Value"]
54    channels_gimp = [HISTOGRAM_VALUE]
55    if drw.is_rgb:
56        channels_txt += ["Red", "Green", "Blue"]
57        channels_gimp += [HISTOGRAM_RED, HISTOGRAM_GREEN, HISTOGRAM_BLUE]
58    if drw.has_alpha:
59        channels_txt += ["Alpha"]
60        channels_gimp += [HISTOGRAM_ALPHA]
61    with open(filename, "wt") as hfile:
62        writer = csv.writer(hfile)
63        #headers:
64        writer.writerow(["Range start"] + channels_txt)
65
66        # FIXME: Will need a specialized 'range' for FP color numbers
67        bucket_size = int(bucket_size)
68        for start_range in range(0, 256, bucket_size):
69            row = [start_range]
70            for channel in channels_gimp:
71                result = pdb.gimp_histogram(
72                             drw, channel,
73                             start_range,
74                             min(start_range + bucket_size - 1, 255)
75                            )
76                if output_format == "pixel count":
77                    count = result[4]
78                else:
79                    count = (result[4] / result[3]) if result[3] else 0
80                    if output_format == "percent":
81                        count = "%.2f%%" % (count * 100)
82                row.append(str(count))
83            writer.writerow(row)
84    if sample_average:
85        pdb.gimp_image_delete(new_img)
86
87register(
88    "histogram-export",
89    N_("Exports the image histogram to a text file (CSV)"),
90    globals()["__doc__"], # This includes the docstring, on the top of the file
91    "João S. O. Bueno",
92    "João S. O. Bueno, 2014",
93    "2014",
94    N_("_Export histogram..."),
95    "*",
96    [(PF_IMAGE,  "img", _("_Image"), None),
97     (PF_DRAWABLE, "drw", _("_Drawable"), None),
98     (PF_FILENAME, "filename", _("Histogram _File"), ""),
99     (PF_FLOAT, "bucket_size", _("_Bucket Size"), 1.0),
100     (PF_BOOL, "sample_average", _("Sample _Average"), False),
101     (PF_RADIO, "output_format", _("Output format"), "pixel count",
102            ((_("Pixel count"), "pixel count"),
103             (_("Normalized"), "normalized"),
104             (_("Percent"), "percent"),
105            )
106     )
107    ],
108    [],
109    histogram_export,
110    menu="<Image>/Colors/Info",
111    domain=("gimp20-python", gimp.locale_directory)
112    )
113
114main()
115