main(int argc, char **argv) { l_int32 i, j, w1, h1, w2, h2, w, h, same; BOX *box1, *box2; PIX *pixs, *pixs1, *pixs2, *pix1, *pix2; PIX *pixg, *pixg1, *pixg2, *pixc2, *pixbl, *pixd; PIXA *pixa; static char mainName[] = "blend2_reg"; /* --- Set up the 8 bpp blending image --- */ pixg = pixCreate(660, 500, 8); for (i = 0; i < 500; i++) for (j = 0; j < 660; j++) pixSetPixel(pixg, j, i, (l_int32)(0.775 * j) % 256); /* --- Set up the initial color images to be blended together --- */ pixs1 = pixRead("wyom.jpg"); pixs2 = pixRead("fish24.jpg"); pixGetDimensions(pixs1, &w1, &h1, NULL); pixGetDimensions(pixs2, &w2, &h2, NULL); h = L_MIN(h1, h2); w = L_MIN(w1, w2); box1 = boxCreate(0, 0, w1, h1); box2 = boxCreate(0, 300, 660, 500); pix1 = pixClipRectangle(pixs1, box1, NULL); pix2 = pixClipRectangle(pixs2, box2, NULL); pixDestroy(&pixs1); pixDestroy(&pixs2); boxDestroy(&box1); boxDestroy(&box2); /* --- Blend 2 rgb images --- */ pixa = pixaCreate(0); pixSaveTiled(pixg, pixa, 1, 1, 40, 32); pixd = pixBlendWithGrayMask(pix1, pix2, pixg, 50, 50); pixSaveTiled(pix1, pixa, 1, 1, 40, 32); pixSaveTiled(pix2, pixa, 1, 0, 40, 32); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixd); /* --- Blend 2 grayscale images --- */ pixg1 = pixConvertRGBToLuminance(pix1); pixg2 = pixConvertRGBToLuminance(pix2); pixd = pixBlendWithGrayMask(pixg1, pixg2, pixg, 50, 50); pixSaveTiled(pixg1, pixa, 1, 1, 40, 32); pixSaveTiled(pixg2, pixa, 1, 0, 40, 32); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixg1); pixDestroy(&pixg2); pixDestroy(&pixd); /* --- Blend a colormap image and an rgb image --- */ pixc2 = pixFixedOctcubeQuantGenRGB(pix2, 2); pixd = pixBlendWithGrayMask(pix1, pixc2, pixg, 50, 50); pixSaveTiled(pix1, pixa, 1, 1, 40, 32); pixSaveTiled(pixc2, pixa, 1, 0, 40, 32); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixc2); pixDestroy(&pixd); /* --- Blend a colormap image and a grayscale image --- */ pixg1 = pixConvertRGBToLuminance(pix1); pixc2 = pixFixedOctcubeQuantGenRGB(pix2, 2); pixd = pixBlendWithGrayMask(pixg1, pixc2, pixg, 50, 50); pixSaveTiled(pixg1, pixa, 1, 1, 40, 32); pixSaveTiled(pixc2, pixa, 1, 0, 40, 32); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixd); pixd = pixBlendWithGrayMask(pixg1, pixc2, pixg, -100, -100); pixSaveTiled(pixg1, pixa, 1, 1, 40, 32); pixSaveTiled(pixc2, pixa, 1, 0, 40, 32); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixd); pixDestroy(&pixg1); pixDestroy(&pixc2); /* --- Test png read/write with alpha channel --- */ /* First make pixs1, using pixg as the alpha channel */ pixs = pixRead("fish24.jpg"); box1 = boxCreate(0, 300, 660, 500); pixs1 = pixClipRectangle(pixs, box1, NULL); pixSaveTiled(pixs1, pixa, 1, 1, 40, 32); pixSetRGBComponent(pixs1, pixg, L_ALPHA_CHANNEL); /* To see the alpha channel, blend with a black image */ pixbl = pixCreate(660, 500, 32); pixd = pixBlendWithGrayMask(pixbl, pixs1, NULL, 0, 0); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixd); /* Write out the RGBA image and read it back */ l_pngSetWriteAlpha(1); pixWrite("/tmp/junkpixs1.png", pixs1, IFF_PNG); l_pngSetStripAlpha(0); pixs2 = pixRead("/tmp/junkpixs1.png"); /* Make sure that the alpha channel image hasn't changed */ pixg2 = pixGetRGBComponent(pixs2, L_ALPHA_CHANNEL); pixEqual(pixg, pixg2, &same); if (same) fprintf(stderr, "PNG with alpha read/write OK\n"); else fprintf(stderr, "PNG with alpha read/write failed\n"); /* Blend again with a black image */ pixd = pixBlendWithGrayMask(pixbl, pixs2, NULL, 0, 0); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixd); /* Blend with a white image */ pixSetAll(pixbl); pixd = pixBlendWithGrayMask(pixbl, pixs2, NULL, 0, 0); pixSaveTiled(pixd, pixa, 1, 0, 40, 32); pixDestroy(&pixd); l_pngSetWriteAlpha(0); /* reset to default */ l_pngSetStripAlpha(1); /* reset to default */ pixDestroy(&pixbl); pixDestroy(&pixs); pixDestroy(&pixs1); pixDestroy(&pixs2); pixDestroy(&pixg2); boxDestroy(&box1); /* --- Display results --- */ pixd = pixaDisplay(pixa, 0, 0); pixDisplay(pixd, 100, 100); pixWrite("/tmp/junkblend2.jpg", pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixg); pixDestroy(&pix1); pixDestroy(&pix2); return 0; }
static l_int32 TestImage(const char *filename, l_int32 i, L_REGPARAMS *rp) { char buf[256]; l_int32 w, h; l_float32 factor; PIX *pix, *pixs, *pixc, *pix32, *pixt, *pixd; PIXA *pixa; PROCNAME("TestImage"); if ((pix = pixRead(filename)) == NULL) { rp->success = FALSE; return ERROR_INT("pix not made", procName, 1); } pixGetDimensions(pix, &w, &h, NULL); if (w > MAX_WIDTH) { factor = (l_float32)MAX_WIDTH / (l_float32)w; pixs = pixScale(pix, factor, factor); } else pixs = pixClone(pix); pixDestroy(&pix); pixa = pixaCreate(0); /* Median cut quantizer (no dither; 5 sigbits) */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 32); pixc = pixMedianCutQuantGeneral(pixs, 0, 0, 16, 5, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 0, 0, 128, 5, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 0, 0, 256, 5, 1, 1); PixSave32(pixa, pixc, rp); /* Median cut quantizer (with dither; 5 sigbits) */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixMedianCutQuantGeneral(pixs, 1, 0, 16, 5, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 1, 0, 128, 5, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 1, 0, 256, 5, 1, 1); PixSave32(pixa, pixc, rp); /* Median cut quantizer (no dither; 6 sigbits) */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 32); pixc = pixMedianCutQuantGeneral(pixs, 0, 0, 16, 6, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 0, 0, 128, 6, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 0, 0, 256, 6, 1, 1); PixSave32(pixa, pixc, rp); /* Median cut quantizer (with dither; 6 sigbits) */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixMedianCutQuantGeneral(pixs, 1, 0, 16, 6, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 1, 0, 128, 6, 1, 1); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantGeneral(pixs, 1, 0, 256, 6, 10, 1); PixSave32(pixa, pixc, rp); /* Median cut quantizer (mixed color/gray) */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixMedianCutQuantMixed(pixs, 20, 10, 0, 0, 0); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantMixed(pixs, 60, 20, 0, 0, 0); PixSave32(pixa, pixc, rp); pixc = pixMedianCutQuantMixed(pixs, 180, 40, 0, 0, 0); PixSave32(pixa, pixc, rp); /* Simple 256 cube octcube quantizer */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixFixedOctcubeQuant256(pixs, 0); /* no dither */ PixSave32(pixa, pixc, rp); pixc = pixFixedOctcubeQuant256(pixs, 1); /* dither */ PixSave32(pixa, pixc, rp); /* 2-pass octree quantizer */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixOctreeColorQuant(pixs, 128, 0); /* no dither */ PixSave32(pixa, pixc, rp); pixc = pixOctreeColorQuant(pixs, 240, 0); /* no dither */ PixSave32(pixa, pixc, rp); pixc = pixOctreeColorQuant(pixs, 128, 1); /* dither */ PixSave32(pixa, pixc, rp); pixc = pixOctreeColorQuant(pixs, 240, 1); /* dither */ PixSave32(pixa, pixc, rp); /* Simple adaptive quantization to 4 or 8 bpp, specifying ncolors */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixOctreeQuantNumColors(pixs, 8, 0); /* fixed: 8 colors */ PixSave32(pixa, pixc, rp); pixc = pixOctreeQuantNumColors(pixs, 16, 0); /* fixed: 16 colors */ PixSave32(pixa, pixc, rp); pixc = pixOctreeQuantNumColors(pixs, 64, 0); /* fixed: 64 colors */ PixSave32(pixa, pixc, rp); pixc = pixOctreeQuantNumColors(pixs, 256, 0); /* fixed: 256 colors */ PixSave32(pixa, pixc, rp); /* Quantize to fully populated octree (RGB) at given level */ pixSaveTiled(pixs, pixa, 1.0, 1, SPACE, 0); pixc = pixFixedOctcubeQuantGenRGB(pixs, 2); /* level 2 */ PixSave32(pixa, pixc, rp); pixc = pixFixedOctcubeQuantGenRGB(pixs, 3); /* level 3 */ PixSave32(pixa, pixc, rp); pixc = pixFixedOctcubeQuantGenRGB(pixs, 4); /* level 4 */ PixSave32(pixa, pixc, rp); pixc = pixFixedOctcubeQuantGenRGB(pixs, 5); /* level 5 */ PixSave32(pixa, pixc, rp); /* Generate 32 bpp RGB image with num colors <= 256 */ pixt = pixOctreeQuantNumColors(pixs, 256, 0); /* cmapped version */ pix32 = pixRemoveColormap(pixt, REMOVE_CMAP_BASED_ON_SRC); /* Quantize image with few colors at fixed octree leaf level */ pixSaveTiled(pixt, pixa, 1.0, 1, SPACE, 0); pixc = pixFewColorsOctcubeQuant1(pix32, 2); /* level 2 */ PixSave32(pixa, pixc, rp); pixc = pixFewColorsOctcubeQuant1(pix32, 3); /* level 3 */ PixSave32(pixa, pixc, rp); pixc = pixFewColorsOctcubeQuant1(pix32, 4); /* level 4 */ PixSave32(pixa, pixc, rp); pixc = pixFewColorsOctcubeQuant1(pix32, 5); /* level 5 */ PixSave32(pixa, pixc, rp); /* Quantize image by population */ pixSaveTiled(pixt, pixa, 1.0, 1, SPACE, 0); pixc = pixOctreeQuantByPopulation(pixs, 3, 0); /* level 3, no dither */ PixSave32(pixa, pixc, rp); pixc = pixOctreeQuantByPopulation(pixs, 3, 1); /* level 3, dither */ PixSave32(pixa, pixc, rp); pixc = pixOctreeQuantByPopulation(pixs, 4, 0); /* level 4, no dither */ PixSave32(pixa, pixc, rp); pixc = pixOctreeQuantByPopulation(pixs, 4, 1); /* level 4, dither */ PixSave32(pixa, pixc, rp); /* Mixed color/gray octree quantizer */ pixSaveTiled(pixt, pixa, 1.0, 1, SPACE, 0); pixc = pixOctcubeQuantMixedWithGray(pix32, 8, 64, 10); /* max delta = 10 */ PixSave32(pixa, pixc, rp); pixc = pixOctcubeQuantMixedWithGray(pix32, 8, 64, 30); /* max delta = 30 */ PixSave32(pixa, pixc, rp); pixc = pixOctcubeQuantMixedWithGray(pix32, 8, 64, 50); /* max delta = 50 */ PixSave32(pixa, pixc, rp); /* Run the high-level converter */ pixSaveTiled(pixt, pixa, 1.0, 1, SPACE, 0); pixc = pixConvertRGBToColormap(pix32, 1); PixSave32(pixa, pixc, rp); pixDestroy(&pix32); pixDestroy(&pixt); pixd = pixaDisplay(pixa, 0, 0); pixDisplayWithTitle(pixd, 100, 100, NULL, rp->display); sprintf(buf, "/tmp/regout/disp.%d.jpg", i); pixWrite(buf, pixd, IFF_JFIF_JPEG); pixDestroy(&pixs); pixDestroy(&pixd); pixaDestroy(&pixa); return 0; }