Example #1
0
static bool is_wide_gamut(const skcms_ICCProfile& profile) {
    // Determine if the source image has a gamut that is wider than sRGB.  If so, we
    // will use P3 as the output color space to avoid clipping the gamut.
    if (profile.has_toXYZD50) {
        SkPoint rgb[3];
        load_gamut(rgb, profile.toXYZD50);
        return calculate_area(rgb) > kSRGB_D50_GamutArea;
    }

    return false;
}
static void draw_gamut(SkCanvas* canvas, const SkMatrix44& xyz, const char* name, SkColor color,
                       bool label) {
    // Report the XYZ values.
    SkDebugf("%s\n", name);
    SkDebugf("          X     Y     Z\n");
    SkDebugf("Red   %.3f %.3f %.3f\n", xyz.get(0, 0), xyz.get(0, 1), xyz.get(0, 2));
    SkDebugf("Green %.3f %.3f %.3f\n", xyz.get(1, 0), xyz.get(1, 1), xyz.get(1, 2));
    SkDebugf("Blue  %.3f %.3f %.3f\n", xyz.get(2, 0), xyz.get(2, 1), xyz.get(2, 2));

    // Calculate the points in the gamut from the XYZ values.
    SkPoint rgb[4];
    load_gamut(rgb, xyz);

    // Report the area of the gamut.
    SkDebugf("Area of Gamut: %.3f\n\n", calculate_area(rgb));

    // Magic constants that help us place the gamut triangles in the appropriate position
    // on the canvas.
    const float xScale = 2071.25f;  // Num pixels from 0 to 1 in x
    const float xOffset = 241.0f;   // Num pixels until start of x-axis
    const float yScale = 2067.78f;  // Num pixels from 0 to 1 in y
    const float yOffset = -144.78f; // Num pixels until start of y-axis
                                    // (negative because y extends beyond image bounds)

    // Now transform the points so they can be drawn on our canvas.
    // Note that y increases as we move down the canvas.
    rgb[0].fX = xOffset + xScale * rgb[0].fX;
    rgb[0].fY = yOffset + yScale * (1.0f - rgb[0].fY);
    rgb[1].fX = xOffset + xScale * rgb[1].fX;
    rgb[1].fY = yOffset + yScale * (1.0f - rgb[1].fY);
    rgb[2].fX = xOffset + xScale * rgb[2].fX;
    rgb[2].fY = yOffset + yScale * (1.0f - rgb[2].fY);

    // Repeat the first point to connect the polygon.
    rgb[3] = rgb[0];
    SkPaint paint;
    paint.setColor(color);
    paint.setStrokeWidth(6.0f);
    paint.setTextSize(75.0f);
    canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, rgb, paint);
    if (label) {
        canvas->drawText("R", 1, rgb[0].fX + 5.0f, rgb[0].fY + 75.0f, paint);
        canvas->drawText("G", 1, rgb[1].fX + 5.0f, rgb[1].fY - 5.0f, paint);
        canvas->drawText("B", 1, rgb[2].fX - 75.0f, rgb[2].fY - 5.0f, paint);
    }
}
Example #3
0
int main(int argc, char** argv) {
    SkCommandLineFlags::SetUsage(
            "Usage: visualize_color_gamut --input <path to input image>"
                                         "--output <path to output image>\n"
            "Description: Writes a visualization of the color gamut to the output image\n");
    SkCommandLineFlags::Parse(argc, argv);
    const char* input = FLAGS_input[0];
    const char* output = FLAGS_output[0];
    if (!input || !output) {
        SkCommandLineFlags::PrintUsage();
        return -1;
    }

    SkAutoTUnref<SkData> data(SkData::NewFromFileName(input));
    if (!data) {
        SkDebugf("Cannot find input image.\n");
        return -1;
    }
    SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data));
    if (!codec) {
        SkDebugf("Invalid input image.\n");
        return -1;
    }

    // Load a graph of the CIE XYZ color gamut.
    SkBitmap bitmap;
    if (!GetResourceAsBitmap("gamut.png", &bitmap)) {
        SkDebugf("Program failure.\n");
        return -1;
    }
    SkCanvas canvas(bitmap);

    sk_sp<SkColorSpace> colorSpace = sk_ref_sp(codec->getColorSpace());
    if (!colorSpace) {
        SkDebugf("Image had no embedded color space information.  Defaulting to sRGB.\n");
        colorSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
    }

    // Calculate the points in the gamut from the XYZ values.
    SkMatrix44 xyz = colorSpace->xyz();
    SkPoint rgb[4];
    load_gamut(rgb, xyz);

    // Report the XYZ values.
    SkDebugf("      X    Y    Z\n");
    SkDebugf("Red   %.2f %.2f %.2f\n", xyz.get(0, 0), xyz.get(0, 1), xyz.get(0, 2));
    SkDebugf("Green %.2f %.2f %.2f\n", xyz.get(1, 0), xyz.get(1, 1), xyz.get(1, 2));
    SkDebugf("Blue  %.2f %.2f %.2f\n", xyz.get(2, 0), xyz.get(2, 1), xyz.get(2, 2));

    // Report the area of the gamut.
    SkDebugf("Area of Gamut: %g\n", calculate_area(rgb));

    // Now transform the points so they can be drawn on our canvas.  We use 1000 pixels
    // to represent the space from 0 to 1.  Note that the graph is at an offset of (50, 50).
    // Also note that y increases as we move down the canvas.
    rgb[0].fX = 50 + 1000*rgb[0].fX;
    rgb[0].fY = 50 + 1000*(1 - rgb[0].fY);
    rgb[1].fX = 50 + 1000*rgb[1].fX;
    rgb[1].fY = 50 + 1000*(1 - rgb[1].fY);
    rgb[2].fX = 50 + 1000*rgb[2].fX;
    rgb[2].fY = 50 + 1000*(1 - rgb[2].fY);

    // Repeat the first point to connect the polygon.
    rgb[3] = rgb[0];

    SkPaint paint;
    canvas.drawPoints(SkCanvas::kPolygon_PointMode, 4, rgb, paint);

    // Finally, encode the result to out.png.
    SkAutoTUnref<SkData> out(SkImageEncoder::EncodeData(bitmap, SkImageEncoder::kPNG_Type, 100));
    if (!out) {
        SkDebugf("Failed to encode output.\n");
        return -1;
    }
    SkFILEWStream stream(output);
    bool result = stream.write(out->data(), out->size());
    if (!result) {
        SkDebugf("Failed to write output.\n");
        return -1;
    }

    return 0;
}