plug-ins: Improve color detection in file-pdf-export
Resolves #14583 If the user chooses to vectorize PDF layers with single colors, get_layer_color () is run to use histograms to determine if they are indeed a single color. gimp_drawable_histogram () is used to get the RGB values as averages. This function returns values in the 0...255 range for 8-bit images and 0.0...1.0 range for all the other precisions. However, we did not properly normalize the values, resulting in blown-out white layers when exporting 8-bit images. This patch checks if the image is 8-bit and divides all values by 255.0f in that case. It also checks if the image is in linear precision or not, as gegl_color_set_rgba () assumes the color values are linear. If not, gegl_color_set_pixel () is used instead. Finally, the color mode checks are made a bit more robust in preparation for future color modes like CMYK.
This commit is contained in:
parent
b41deb138d
commit
d88cd4cb7a
1 changed files with 50 additions and 22 deletions
|
|
@ -487,8 +487,8 @@ pdf_export (GimpProcedure *procedure,
|
||||||
GimpProcedureConfig *config,
|
GimpProcedureConfig *config,
|
||||||
gpointer run_data)
|
gpointer run_data)
|
||||||
{
|
{
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
GimpPDBStatusType status = GIMP_PDB_SUCCESS;
|
||||||
|
|
||||||
gegl_init (NULL, NULL);
|
gegl_init (NULL, NULL);
|
||||||
|
|
||||||
|
|
@ -1454,24 +1454,22 @@ get_cairo_surface (GimpDrawable *drawable,
|
||||||
return surface;
|
return surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A function to check if a drawable is single colored This allows to
|
/* A function to check if a drawable is single colored. This allows to
|
||||||
* convert bitmaps to vector where possible
|
* convert bitmaps to vector where possible
|
||||||
*/
|
*/
|
||||||
static GeglColor *
|
static GeglColor *
|
||||||
get_layer_color (GimpLayer *layer,
|
get_layer_color (GimpLayer *layer,
|
||||||
gboolean *single)
|
gboolean *single)
|
||||||
{
|
{
|
||||||
GeglColor *col = gegl_color_new (NULL);
|
GeglColor *col = gegl_color_new (NULL);
|
||||||
gdouble red, green, blue, alpha;
|
gdouble rgba[4] = { 0, 0, 0, 0 };
|
||||||
gdouble dev, devSum;
|
gdouble dev, devSum;
|
||||||
gdouble median, pixels, count, percentile;
|
gdouble median, pixels, count, percentile;
|
||||||
|
gint bpp;
|
||||||
|
|
||||||
devSum = 0;
|
devSum = 0;
|
||||||
red = 0;
|
dev = 0;
|
||||||
green = 0;
|
bpp = gimp_drawable_get_bpp (GIMP_DRAWABLE (layer));
|
||||||
blue = 0;
|
|
||||||
alpha = 0;
|
|
||||||
dev = 0;
|
|
||||||
|
|
||||||
if (gimp_drawable_is_indexed (GIMP_DRAWABLE (layer)))
|
if (gimp_drawable_is_indexed (GIMP_DRAWABLE (layer)))
|
||||||
{
|
{
|
||||||
|
|
@ -1481,23 +1479,26 @@ get_layer_color (GimpLayer *layer,
|
||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gimp_drawable_get_bpp (GIMP_DRAWABLE (layer)) >= 3)
|
if (gimp_drawable_is_rgb (GIMP_DRAWABLE (layer)))
|
||||||
{
|
{
|
||||||
/* Are we in RGB mode? */
|
/* Are we in RGB mode? */
|
||||||
|
|
||||||
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
||||||
GIMP_HISTOGRAM_RED, 0.0, 1.0,
|
GIMP_HISTOGRAM_RED, 0.0, 1.0,
|
||||||
&red, &dev, &median, &pixels, &count, &percentile);
|
&rgba[0], &dev, &median, &pixels, &count,
|
||||||
|
&percentile);
|
||||||
devSum += dev;
|
devSum += dev;
|
||||||
|
|
||||||
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
||||||
GIMP_HISTOGRAM_GREEN, 0.0, 1.0,
|
GIMP_HISTOGRAM_GREEN, 0.0, 1.0,
|
||||||
&green, &dev, &median, &pixels, &count, &percentile);
|
&rgba[1], &dev, &median, &pixels, &count,
|
||||||
|
&percentile);
|
||||||
devSum += dev;
|
devSum += dev;
|
||||||
|
|
||||||
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
||||||
GIMP_HISTOGRAM_BLUE, 0.0, 1.0,
|
GIMP_HISTOGRAM_BLUE, 0.0, 1.0,
|
||||||
&blue, &dev, &median, &pixels, &count, &percentile);
|
&rgba[2], &dev, &median, &pixels, &count,
|
||||||
|
&percentile);
|
||||||
devSum += dev;
|
devSum += dev;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -1506,23 +1507,50 @@ get_layer_color (GimpLayer *layer,
|
||||||
|
|
||||||
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
||||||
GIMP_HISTOGRAM_VALUE, 0.0, 1.0,
|
GIMP_HISTOGRAM_VALUE, 0.0, 1.0,
|
||||||
&red, &dev, &median, &pixels, &count, &percentile);
|
&rgba[0], &dev, &median, &pixels, &count,
|
||||||
|
&percentile);
|
||||||
devSum += dev;
|
devSum += dev;
|
||||||
green = red;
|
rgba[1] = rgba[0];
|
||||||
blue = red;
|
rgba[2] = rgba[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
|
if (gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
|
||||||
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
gimp_drawable_histogram (GIMP_DRAWABLE (layer),
|
||||||
GIMP_HISTOGRAM_ALPHA, 0.0, 1.0,
|
GIMP_HISTOGRAM_ALPHA, 0.0, 1.0,
|
||||||
&alpha, &dev, &median, &pixels, &count, &percentile);
|
&rgba[3], &dev, &median, &pixels, &count,
|
||||||
|
&percentile);
|
||||||
else
|
else
|
||||||
alpha = 255;
|
rgba[3] = 255.0f;
|
||||||
|
|
||||||
devSum += dev;
|
devSum += dev;
|
||||||
*single = devSum == 0;
|
*single = devSum == 0;
|
||||||
|
|
||||||
gegl_color_set_rgba (col, red, green, blue, alpha);
|
/* If the image is 8-bit, we need to normalize the RGB values that are
|
||||||
|
* returned in the 0...255 range */
|
||||||
|
bpp -= gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)) ? 1 : 0;
|
||||||
|
if ((gimp_drawable_is_rgb (GIMP_DRAWABLE (layer)) && bpp == 3) ||
|
||||||
|
bpp == 1)
|
||||||
|
{
|
||||||
|
for (gint i = 0; i < 4; i++)
|
||||||
|
rgba[i] /= 255.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gimp_image_get_precision (gimp_item_get_image (GIMP_ITEM (layer))))
|
||||||
|
{
|
||||||
|
case GIMP_PRECISION_U8_LINEAR:
|
||||||
|
case GIMP_PRECISION_U16_LINEAR:
|
||||||
|
case GIMP_PRECISION_U32_LINEAR:
|
||||||
|
case GIMP_PRECISION_HALF_LINEAR:
|
||||||
|
case GIMP_PRECISION_FLOAT_LINEAR:
|
||||||
|
case GIMP_PRECISION_DOUBLE_LINEAR:
|
||||||
|
gegl_color_set_rgba (col, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
gegl_color_set_pixel (col, babl_format ("R'G'B'A double"), rgba);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return col;
|
return col;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue