/*! * bmfCreate() * * Input: dir (directory holding pixa of character set) * size (4, 6, 8, ... , 20) * Return: bmf (holding the bitmap font and associated information) * * Notes: * (1) This first tries to read a pre-computed pixa file with the * 95 ascii chars in it. If the file is not found, it * creates the pixa from the raw image. It then generates all * associated data required to use the bmf. */ L_BMF * bmfCreate(const char *dir, l_int32 size) { L_BMF *bmf; PIXA *pixa; PROCNAME("bmfCreate"); if ((bmf = (L_BMF *)CALLOC(1, sizeof(L_BMF))) == NULL) return (L_BMF *)ERROR_PTR("bmf not made", procName, NULL); /* Look for the pixa */ pixa = pixaGetFont(dir, size, &bmf->baseline1, &bmf->baseline2, &bmf->baseline3); /* If not found, make it */ if (!pixa) { L_INFO("Generating pixa of bitmap fonts", procName); pixa = pixaGenerateFont(dir, size, &bmf->baseline1, &bmf->baseline2, &bmf->baseline3); if (!pixa) { bmfDestroy(&bmf); return (L_BMF *)ERROR_PTR("font pixa not made", procName, NULL); } } bmf->pixa = pixa; bmf->size = size; bmf->directory = stringNew(dir); bmfMakeAsciiTables(bmf); return bmf; }
l_int32 main(int argc, char **argv) { l_int32 index; L_BMF *bmf; PROCNAME("adaptmap_dark"); bmf = bmfCreate("fonts", 10); index = 0; lept_mkdir("lept"); /* Using a variety of different thresholds */ GenCleans("cavalerie.29.jpg", &index, 80, bmf); GenCleans("cavalerie.29.jpg", &index, 60, bmf); GenCleans("cavalerie.29.jpg", &index, 40, bmf); GenCleans("cavalerie.11.jpg", &index, 80, bmf); GenCleans("cavalerie.11.jpg", &index, 60, bmf); GenCleans("cavalerie.11.jpg", &index, 40, bmf); /* Write the nup files in /tmp/adapt2 */ convertToNUpFiles("/tmp/lept", "adapt_", 2, 1, 500, 6, 2, NULL, "adapt2"); /* Gather up into a pdf */ L_INFO("Writing to /tmp/lept/adapt_cleaning.pdf\n", procName); convertFilesToPdf("/tmp/lept", "adapt_", 100, 1.0, L_JPEG_ENCODE, 75, "Adaptive cleaning", "/tmp/lept/adapt_cleaning.pdf"); bmfDestroy(&bmf); lept_rmdir("adapt2"); return 0; }
/* ----------------------------------------------------- */ void PixaDisplayNumbered(PIXA *pixa, const char *basename) { char buf[64]; l_int32 fill, color, d; L_BMF *bmf; PIX *pix1; PIXA *pixa1, *pixa2; bmf = bmfCreate(NULL, 4); pixaGetPixDimensions(pixa, 0, NULL, NULL, &d); fill = (d == 8) ? 0xff : 0; color = (d == 8) ? 0x00000000 : 0xffffff00; pixa1 = pixaAddBorderGeneral(NULL, pixa, 10, 10, 0, 0, fill); pixa2 = pixaAddTextNumber(pixa1, bmf, NULL, color, L_ADD_BELOW); snprintf(buf, sizeof(buf), "%s.pa", basename); pixaWrite(buf, pixa2); pix1 = pixaDisplayTiledInColumns(pixa2, 20, 2.5, 15, 2); snprintf(buf, sizeof(buf), "%s.png", basename); pixWrite(buf, pix1, IFF_PNG); pixDisplay(pix1, 500, 500); pixDestroy(&pix1); pixaDestroy(&pixa1); pixaDestroy(&pixa2); bmfDestroy(&bmf); }
/*! * \brief recogShowPath() * * \param[in] recog with LUT's pre-computed * \param[in] select 0 for Viterbi; 1 for rescored * \return pix debug output), or NULL on error */ static PIX * recogShowPath(L_RECOG *recog, l_int32 select) { char textstr[16]; l_int32 i, n, index, xloc, dely; l_float32 score; L_BMF *bmf; NUMA *natempl_s, *nascore_s, *naxloc_s, *nadely_s; PIX *pixs, *pix0, *pix1, *pix2, *pix3, *pix4, *pix5; L_RDID *did; PROCNAME("recogShowPath"); if (!recog) return (PIX *)ERROR_PTR("recog not defined", procName, NULL); if ((did = recogGetDid(recog)) == NULL) return (PIX *)ERROR_PTR("did not defined", procName, NULL); bmf = bmfCreate(NULL, 8); pixs = pixScale(did->pixs, 4.0, 4.0); pix0 = pixAddBorderGeneral(pixs, 0, 0, 0, 40, 0); pix1 = pixConvertTo32(pix0); if (select == 0) { /* Viterbi */ natempl_s = did->natempl; nascore_s = did->nascore; naxloc_s = did->naxloc; nadely_s = did->nadely; } else { /* rescored */ natempl_s = did->natempl_r; nascore_s = did->nascore_r; naxloc_s = did->naxloc_r; nadely_s = did->nadely_r; } n = numaGetCount(natempl_s); for (i = 0; i < n; i++) { numaGetIValue(natempl_s, i, &index); pix2 = pixaGetPix(recog->pixa_u, index, L_CLONE); pix3 = pixScale(pix2, 4.0, 4.0); pix4 = pixErodeBrick(NULL, pix3, 5, 5); pixXor(pix4, pix4, pix3); numaGetFValue(nascore_s, i, &score); snprintf(textstr, sizeof(textstr), "%5.3f", score); pix5 = pixAddTextlines(pix4, bmf, textstr, 1, L_ADD_BELOW); numaGetIValue(naxloc_s, i, &xloc); numaGetIValue(nadely_s, i, &dely); pixPaintThroughMask(pix1, pix5, 4 * xloc, 4 * dely, 0xff000000); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); } pixDestroy(&pixs); pixDestroy(&pix0); bmfDestroy(&bmf); return pix1; }
/*! * recogDestroy() * * Input: &recog (<will be set to null before returning>) * Return: void * * Notes: * (1) If a recog has a parent, the parent owns it. A recogDestroy() * will fail if there is a parent. */ void recogDestroy(L_RECOG **precog) { L_RECOG *recog; PROCNAME("recogDestroy"); if (!precog) { L_WARNING("ptr address is null\n", procName); return; } if ((recog = *precog) == NULL) return; if (recogGetParent(recog) != NULL) { L_ERROR("recog has parent; can't be destroyed\n", procName); return; } FREE(recog->bootdir); FREE(recog->bootpattern); FREE(recog->bootpath); FREE(recog->centtab); FREE(recog->sumtab); FREE(recog->fname); sarrayDestroy(&recog->sa_text); l_dnaDestroy(&recog->dna_tochar); pixaaDestroy(&recog->pixaa_u); pixaDestroy(&recog->pixa_u); ptaaDestroy(&recog->ptaa_u); ptaDestroy(&recog->pta_u); numaDestroy(&recog->nasum_u); numaaDestroy(&recog->naasum_u); pixaaDestroy(&recog->pixaa); pixaDestroy(&recog->pixa); ptaaDestroy(&recog->ptaa); ptaDestroy(&recog->pta); numaDestroy(&recog->nasum); numaaDestroy(&recog->naasum); pixaDestroy(&recog->pixa_tr); pixaDestroy(&recog->pixadb_ave); pixaDestroy(&recog->pixa_id); pixDestroy(&recog->pixdb_ave); pixDestroy(&recog->pixdb_range); pixaDestroy(&recog->pixadb_boot); pixaDestroy(&recog->pixadb_split); FREE(recog->fontdir); bmfDestroy(&recog->bmf); rchDestroy(&recog->rch); rchaDestroy(&recog->rcha); recogDestroyDid(recog); FREE(recog); *precog = NULL; return; }
/*! * bmfCreate() * * Input: dir (<optional> directory holding pixa of character set) * fontsize (4, 6, 8, ... , 20) * Return: bmf (holding the bitmap font and associated information) * * Notes: * (1) If @dir == null, this generates the font bitmaps from a * compiled string. * (2) Otherwise, this tries to read a pre-computed pixa file with the * 95 ascii chars in it. If the file is not found, it then * attempts to generate the pixa and associated baseline * data from a tiff image containing all the characters. If * that fails, it uses the compiled string. */ L_BMF * bmfCreate(const char *dir, l_int32 fontsize) { L_BMF *bmf; PIXA *pixa; PROCNAME("bmfCreate"); if (fontsize < 4 || fontsize > 20 || (fontsize % 2)) return (L_BMF *)ERROR_PTR("fontsize must be in {4, 6, ..., 20}", procName, NULL); if ((bmf = (L_BMF *)CALLOC(1, sizeof(L_BMF))) == NULL) return (L_BMF *)ERROR_PTR("bmf not made", procName, NULL); if (!dir) { /* Generate from a string */ L_INFO("Generating pixa of bitmap fonts from string\n", procName); pixa = pixaGenerateFontFromString(fontsize, &bmf->baseline1, &bmf->baseline2, &bmf->baseline3); } else { /* Look for the pixa in a directory */ L_INFO("Locating pixa of bitmap fonts in a file\n", procName); pixa = pixaGetFont(dir, fontsize, &bmf->baseline1, &bmf->baseline2, &bmf->baseline3); if (!pixa) { /* Not found; make it from a file */ L_INFO("Generating pixa of bitmap fonts from file\n", procName); pixa = pixaGenerateFontFromFile(dir, fontsize, &bmf->baseline1, &bmf->baseline2, &bmf->baseline3); if (!pixa) { /* Not made; make it from a string after all */ L_ERROR("Failed to make font; use string\n", procName); pixa = pixaGenerateFontFromString(fontsize, &bmf->baseline1, &bmf->baseline2, &bmf->baseline3); } } } if (!pixa) { bmfDestroy(&bmf); return (L_BMF *)ERROR_PTR("font pixa not made", procName, NULL); } bmf->pixa = pixa; bmf->size = fontsize; if (dir) bmf->directory = stringNew(dir); bmfMakeAsciiTables(bmf); return bmf; }
/*! * \brief fpixaDisplayQuadtree() * * \param[in] fpixa mean, variance or root variance * \param[in] factor replication factor at lowest level * \param[in] fontsize 4, ... 20 * \return pixd 8 bpp, mosaic of quadtree images, or NULL on error * * <pre> * Notes: * (1) The mean and root variance fall naturally in the 8 bpp range, * but the variance is typically outside the range. This * function displays 8 bpp pix clipped to 255, so the image * pixels will mostly be 255 (white). * </pre> */ PIX * fpixaDisplayQuadtree(FPIXA *fpixa, l_int32 factor, l_int32 fontsize) { char buf[256]; l_int32 nlevels, i, mag, w; L_BMF *bmf; FPIX *fpix; PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixd; PIXA *pixat; PROCNAME("fpixaDisplayQuadtree"); if (!fpixa) return (PIX *)ERROR_PTR("fpixa not defined", procName, NULL); if ((nlevels = fpixaGetCount(fpixa)) == 0) return (PIX *)ERROR_PTR("pixas empty", procName, NULL); if ((bmf = bmfCreate(NULL, fontsize)) == NULL) L_ERROR("bmf not made; text will not be added", procName); pixat = pixaCreate(nlevels); for (i = 0; i < nlevels; i++) { fpix = fpixaGetFPix(fpixa, i, L_CLONE); pixt1 = fpixConvertToPix(fpix, 8, L_CLIP_TO_ZERO, 0); mag = factor * (1 << (nlevels - i - 1)); pixt2 = pixExpandReplicate(pixt1, mag); pixt3 = pixConvertTo32(pixt2); snprintf(buf, sizeof(buf), "Level %d\n", i); pixt4 = pixAddSingleTextblock(pixt3, bmf, buf, 0xff000000, L_ADD_BELOW, NULL); pixaAddPix(pixat, pixt4, L_INSERT); fpixDestroy(&fpix); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); } w = pixGetWidth(pixt4); pixd = pixaDisplayTiledInRows(pixat, 32, nlevels * (w + 80), 1.0, 0, 30, 2); pixaDestroy(&pixat); bmfDestroy(&bmf); return pixd; }
/*! * \brief recogDestroy() * * \param[in,out] precog will be set to null before returning * \return void */ void recogDestroy(L_RECOG **precog) { L_RECOG *recog; PROCNAME("recogDestroy"); if (!precog) { L_WARNING("ptr address is null\n", procName); return; } if ((recog = *precog) == NULL) return; LEPT_FREE(recog->centtab); LEPT_FREE(recog->sumtab); sarrayDestroy(&recog->sa_text); l_dnaDestroy(&recog->dna_tochar); pixaaDestroy(&recog->pixaa_u); pixaDestroy(&recog->pixa_u); ptaaDestroy(&recog->ptaa_u); ptaDestroy(&recog->pta_u); numaDestroy(&recog->nasum_u); numaaDestroy(&recog->naasum_u); pixaaDestroy(&recog->pixaa); pixaDestroy(&recog->pixa); ptaaDestroy(&recog->ptaa); ptaDestroy(&recog->pta); numaDestroy(&recog->nasum); numaaDestroy(&recog->naasum); pixaDestroy(&recog->pixa_tr); pixaDestroy(&recog->pixadb_ave); pixaDestroy(&recog->pixa_id); pixDestroy(&recog->pixdb_ave); pixDestroy(&recog->pixdb_range); pixaDestroy(&recog->pixadb_boot); pixaDestroy(&recog->pixadb_split); bmfDestroy(&recog->bmf); rchDestroy(&recog->rch); rchaDestroy(&recog->rcha); recogDestroyDid(recog); LEPT_FREE(recog); *precog = NULL; return; }
int main(int argc, char **argv) { char buf[256]; l_int32 w, h, i, j, k, index, op, dir, stretch; l_float32 del, angle, angledeg; BOX *box; L_BMF *bmf; PIX *pixs, *pix1, *pix2, *pixd; PIXA *pixa; static char mainName[] = "warpertest"; if (argc != 1) return ERROR_INT("syntax: warpertest", mainName, 1); bmf = bmfCreate(NULL, 6); /* -------- Stereoscopic warping --------------*/ #if RUN_WARP pixs = pixRead("german.png"); pixGetDimensions(pixs, &w, &h, NULL); pixa = pixaCreate(50); for (i = 0; i < 50; i++) { /* need to test > 2 widths ! */ j = 7 * i; box = boxCreate(0, 0, w - j, h - j); pix1 = pixClipRectangle(pixs, box, NULL); pixd = pixWarpStereoscopic(pix1, 15, 22, 8, 30, -20, 1); pixSetChromaSampling(pixd, 0); pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pix1); boxDestroy(&box); } pixDestroy(&pixs); pixaConvertToPdf(pixa, 100, 1.0, L_JPEG_ENCODE, 0, "warp.pdf", "/tmp/warp.pdf"); pixd = pixaDisplayTiledInRows(pixa, 32, 2000, 1.0, 0, 20, 2); pixWrite("/tmp/warp.jpg", pixd, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixd); #endif /* -------- Quadratic Vertical Shear --------------*/ #if RUN_QUAD_VERT_SHEAR pixs = pixCreate(501, 501, 32); pixGetDimensions(pixs, &w, &h, NULL); pixSetAll(pixs); pixRenderLineArb(pixs, 0, 30, 500, 30, 5, 0, 0, 255); pixRenderLineArb(pixs, 0, 110, 500, 110, 5, 0, 255, 0); pixRenderLineArb(pixs, 0, 190, 500, 190, 5, 0, 255, 255); pixRenderLineArb(pixs, 0, 270, 500, 270, 5, 255, 0, 0); pixRenderLineArb(pixs, 0, 360, 500, 360, 5, 255, 0, 255); pixRenderLineArb(pixs, 0, 450, 500, 450, 5, 255, 255, 0); pixa = pixaCreate(50); for (i = 0; i < 50; i++) { j = 3 * i; dir = ((i / 2) & 1) ? L_WARP_TO_RIGHT : L_WARP_TO_LEFT; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; box = boxCreate(0, 0, w - j, h - j); pix1 = pixClipRectangle(pixs, box, NULL); pix2 = pixQuadraticVShear(pix1, dir, 60, -20, op, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%s, %s", dirstr[dir], opstr[op]); pixd = pixAddSingleTextblock(pix2, bmf, buf, 0xff000000, L_ADD_BELOW, 0); pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); boxDestroy(&box); } pixDestroy(&pixs); pixaConvertToPdf(pixa, 100, 1.0, L_FLATE_ENCODE, 0, "quad_vshear.pdf", "/tmp/quad_vshear.pdf"); pixd = pixaDisplayTiledInRows(pixa, 32, 2000, 1.0, 0, 20, 2); pixWrite("/tmp/quad_vshear.jpg", pixd, IFF_PNG); pixaDestroy(&pixa); pixDestroy(&pixd); #endif /* -------- Linear Horizontal stretching --------------*/ #if RUN_LIN_HORIZ_STRETCH pixs = pixRead("german.png"); pixa = pixaCreate(50); for (k = 0; k < 2; k++) { for (i = 0; i < 25; i++) { index = 25 * k + i; stretch = 10 + 4 * i; if (k == 0) stretch = -stretch; dir = (k == 1) ? L_WARP_TO_RIGHT : L_WARP_TO_LEFT; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; pix1 = pixStretchHorizontal(pixs, dir, L_LINEAR_WARP, stretch, op, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%s, %s", dirstr[dir], opstr[op]); pixd = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000, L_ADD_BELOW, 0); pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pix1); } } pixDestroy(&pixs); pixaConvertToPdf(pixa, 100, 1.0, L_JPEG_ENCODE, 0, "linear_hstretch.pdf", "/tmp/linear_hstretch.pdf"); pixd = pixaDisplayTiledInRows(pixa, 32, 2500, 1.0, 0, 20, 2); pixWrite("/tmp/linear_hstretch.jpg", pixd, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixd); #endif /* -------- Quadratic Horizontal stretching --------------*/ #if RUN_QUAD_HORIZ_STRETCH pixs = pixRead("german.png"); pixa = pixaCreate(50); for (k = 0; k < 2; k++) { for (i = 0; i < 25; i++) { index = 25 * k + i; stretch = 10 + 4 * i; if (k == 0) stretch = -stretch; dir = (k == 1) ? L_WARP_TO_RIGHT : L_WARP_TO_LEFT; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; pix1 = pixStretchHorizontal(pixs, dir, L_QUADRATIC_WARP, stretch, op, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%s, %s", dirstr[dir], opstr[op]); pixd = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000, L_ADD_BELOW, 0); pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pix1); } } pixDestroy(&pixs); pixaConvertToPdf(pixa, 100, 1.0, L_JPEG_ENCODE, 0, "quad_hstretch.pdf", "/tmp/quad_hstretch.pdf"); pixd = pixaDisplayTiledInRows(pixa, 32, 2500, 1.0, 0, 20, 2); pixWrite("/tmp/quad_hstretch.jpg", pixd, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixd); #endif /* -------- Horizontal Shear --------------*/ #if RUN_HORIZ_SHEAR pixs = pixRead("german.png"); pixGetDimensions(pixs, &w, &h, NULL); pixa = pixaCreate(50); for (i = 0; i < 25; i++) { del = 0.2 / 12.; angle = -0.2 + (i - (i & 1)) * del; angledeg = 180. * angle / 3.14159265; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; if (op == L_SAMPLED) pix1 = pixHShear(NULL, pixs, h / 2, angle, L_BRING_IN_WHITE); else pix1 = pixHShearLI(pixs, h / 2, angle, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%6.2f degree, %s", angledeg, opstr[op]); pixd = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000, L_ADD_BELOW, 0); pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pix1); } pixDestroy(&pixs); pixaConvertToPdf(pixa, 100, 1.0, L_JPEG_ENCODE, 0, "hshear.pdf", "/tmp/hshear.pdf"); pixd = pixaDisplayTiledInRows(pixa, 32, 2500, 1.0, 0, 20, 2); pixWrite("/tmp/hshear.jpg", pixd, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixd); #endif /* -------- Vertical Shear --------------*/ #if RUN_VERT_SHEAR pixs = pixRead("german.png"); pixGetDimensions(pixs, &w, &h, NULL); pixa = pixaCreate(50); for (i = 0; i < 25; i++) { del = 0.2 / 12.; angle = -0.2 + (i - (i & 1)) * del; angledeg = 180. * angle / 3.14159265; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; if (op == L_SAMPLED) pix1 = pixVShear(NULL, pixs, w / 2, angle, L_BRING_IN_WHITE); else pix1 = pixVShearLI(pixs, w / 2, angle, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%6.2f degree, %s", angledeg, opstr[op]); pixd = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000, L_ADD_BELOW, 0); pixaAddPix(pixa, pixd, L_INSERT); pixDestroy(&pix1); } pixDestroy(&pixs); pixaConvertToPdf(pixa, 100, 1.0, L_JPEG_ENCODE, 0, "vshear.pdf", "/tmp/vshear.pdf"); pixd = pixaDisplayTiledInRows(pixa, 32, 2500, 1.0, 0, 20, 2); pixWrite("/tmp/vshear.jpg", pixd, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixd); #endif bmfDestroy(&bmf); return 0; }
main(int argc, char **argv) { char *filein, *fileout, *textstr; l_int32 i, d, size, width, wtext, overflow; l_uint32 val; L_BMF *bmf; PIX *pixs, *pix; static char mainName[] = "renderfonts"; if (argc != 4) exit(ERROR_INT("Syntax: renderfonts filein size fileout", mainName, 1)); filein = argv[1]; size = atoi(argv[2]); fileout = argv[3]; if ((pixs = pixRead(filein)) == NULL) exit(ERROR_INT("pixs not made", mainName, 1)); d = pixGetDepth(pixs); if (d == 8) val = 128; else if (d == 16) val = 0x8000; else if (d == 32) composeRGBPixel(128, 0, 255, &val); else exit(ERROR_INT("pixs not 8, 16 or 32 bpp", mainName, 1)); bmf = bmfCreate(DIRECTORY, size); #if 0 /* render a character of text */ pix = pixaGetPix(bmf->pixa, 45, L_CLONE); startTimer(); for (i = 0; i < 10000; i++) pixSetMaskedGeneral(pixs, pix, val, 150, 150); fprintf(stderr, "time: %7.3f sec\n", stopTimer()); pixWrite(fileout, pixs, IFF_JFIF_JPEG); pixDestroy(&pix); #endif #if 0 /* render a line of text; use marge.jpg with size 14 */ bmfGetStringWidth(bmf, "This is a funny cat!", &width); fprintf(stderr, "String width: %d pixels\n", width); pixSetTextline(pixs, bmf, "This is a funny cat!", 0x8000ff00, 50, 250, &width, &overflow); pixWrite(fileout, pixs, IFF_JFIF_JPEG); fprintf(stderr, "Text width = %d\n", width); if (overflow) fprintf(stderr, "Text overflow beyond image boundary\n"); #endif #if 1 /* render a block of text; use marge.jpg with size 14 */ textstr = stringNew("This is a cat! This is a funny cat! This is a funny funny cat! This is a funny funny funny cat!"); wtext = pixGetWidth(pixs) - 70; pixSetTextblock(pixs, bmf, textstr, 0x4040ff00, 50, 50, wtext, 1, &overflow); pixWrite(fileout, pixs, IFF_JFIF_JPEG); if (overflow) fprintf(stderr, "Text overflow beyond image boundary\n"); lept_free(textstr); #endif pixDestroy(&pixs); bmfDestroy(&bmf); return 0; }
int main(int argc, char **argv) { char textstr[256]; l_int32 w, h, d, i; l_uint32 srcval, dstval; l_float32 scalefact, sat, fract; L_BMF *bmf8; L_KERNEL *kel; NUMA *na; PIX *pix, *pixs, *pixs1, *pixs2, *pixd; PIX *pixt0, *pixt1, *pixt2, *pixt3, *pixt4; PIXA *pixa, *pixaf; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pix = pixRead(filein); pixGetDimensions(pix, &w, &h, &d); if (d != 32) return ERROR_INT("file not 32 bpp", argv[0], 1); scalefact = (l_float32)WIDTH / (l_float32)w; pixs = pixScale(pix, scalefact, scalefact); w = pixGetWidth(pixs); pixaf = pixaCreate(5); /* TRC: vary gamma */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixGammaTRC(NULL, pixs, 0.3 + 0.15 * i, 0, 255); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 32); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 0 */ pixDisplayWithTitle(pixt1, 0, 100, "TRC Gamma", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* TRC: vary black point */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixGammaTRC(NULL, pixs, 1.0, 5 * i, 255); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 1 */ pixDisplayWithTitle(pixt1, 300, 100, "TRC", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary hue */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixModifyHue(NULL, pixs, 0.01 + 0.05 * i); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 2 */ pixDisplayWithTitle(pixt1, 600, 100, "Hue", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary saturation */ pixa = pixaCreate(20); na = numaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixModifySaturation(NULL, pixs, -0.9 + 0.1 * i); pixMeasureSaturation(pixt0, 1, &sat); pixaAddPix(pixa, pixt0, L_INSERT); numaAddNumber(na, sat); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); gplotSimple1(na, GPLOT_PNG, "/tmp/regout/enhance.7", "Average Saturation"); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 3 */ pixDisplayWithTitle(pixt1, 900, 100, "Saturation", rp->display); numaDestroy(&na); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary contrast */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixContrastTRC(NULL, pixs, 0.1 * i); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 4 */ pixDisplayWithTitle(pixt1, 0, 400, "Contrast", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Vary sharpening */ pixa = pixaCreate(20); for (i = 0; i < 20; i++) { pixt0 = pixUnsharpMasking(pixs, 3, 0.01 + 0.15 * i); pixaAddPix(pixa, pixt0, L_INSERT); } pixt1 = pixaDisplayTiledAndScaled(pixa, 32, w, 5, 0, 10, 2); pixSaveTiled(pixt1, pixaf, 1.0, 1, 20, 0); regTestWritePixAndCheck(rp, pixt1, IFF_PNG); /* 5 */ pixDisplayWithTitle(pixt1, 300, 400, "Sharp", rp->display); pixDestroy(&pixt1); pixaDestroy(&pixa); /* Hue constant mapping to lighter background */ pixa = pixaCreate(11); bmf8 = bmfCreate("fonts", 8); pixt0 = pixRead("candelabrum-11.jpg"); composeRGBPixel(230, 185, 144, &srcval); /* select typical bg pixel */ for (i = 0; i <= 10; i++) { fract = 0.10 * i; pixelFractionalShift(230, 185, 144, fract, &dstval); pixt1 = pixLinearMapToTargetColor(NULL, pixt0, srcval, dstval); snprintf(textstr, 50, "Fract = %5.1f", fract); pixt2 = pixAddSingleTextblock(pixt1, bmf8, textstr, 0xff000000, L_ADD_BELOW, NULL); pixSaveTiledOutline(pixt2, pixa, 1.0, (i % 4 == 0) ? 1 : 0, 30, 2, 32); pixDestroy(&pixt1); pixDestroy(&pixt2); } pixDestroy(&pixt0); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 6 */ pixDisplayWithTitle(pixd, 600, 400, "Constant hue", rp->display); bmfDestroy(&bmf8); pixaDestroy(&pixa); pixDestroy(&pixd); /* Delayed testing of saturation plot */ regTestCheckFile(rp, "/tmp/regout/enhance.7.png"); /* 7 */ /* Display results */ pixd = pixaDisplay(pixaf, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 8 */ pixDisplayWithTitle(pixd, 100, 100, "All", rp->display); pixDestroy(&pixd); pixaDestroy(&pixaf); pixDestroy(&pix); pixDestroy(&pixs); /* -----------------------------------------------* * Test global color transforms * * -----------------------------------------------*/ /* Make identical cmap and rgb images */ pix = pixRead("wet-day.jpg"); pixs1 = pixOctreeColorQuant(pix, 200, 0); pixs2 = pixRemoveColormap(pixs1, REMOVE_CMAP_TO_FULL_COLOR); regTestComparePix(rp, pixs1, pixs2); /* 9 */ /* Make a diagonal color transform matrix */ kel = kernelCreate(3, 3); kernelSetElement(kel, 0, 0, 0.7); kernelSetElement(kel, 1, 1, 0.4); kernelSetElement(kel, 2, 2, 1.3); /* Apply to both cmap and rgb images. */ pixt1 = pixMultMatrixColor(pixs1, kel); pixt2 = pixMultMatrixColor(pixs2, kel); regTestComparePix(rp, pixt1, pixt2); /* 10 */ kernelDestroy(&kel); /* Apply the same transform in the simpler interface */ pixt3 = pixMultConstantColor(pixs1, 0.7, 0.4, 1.3); pixt4 = pixMultConstantColor(pixs2, 0.7, 0.4, 1.3); regTestComparePix(rp, pixt3, pixt4); /* 11 */ regTestComparePix(rp, pixt1, pixt3); /* 12 */ regTestWritePixAndCheck(rp, pixt1, IFF_JFIF_JPEG); /* 13 */ pixDestroy(&pix); pixDestroy(&pixs1); pixDestroy(&pixs2); pixDestroy(&pixt1); pixDestroy(&pixt2); pixDestroy(&pixt3); pixDestroy(&pixt4); return regTestCleanup(rp); }
/*! * dewarpaShowArrays() * * Input: dewa * scalefact (on contour images; typ. 0.5) * first (first page model to render) * last (last page model to render; use 0 to go to end) * fontdir (for text bitmap fonts) * Return: 0 if OK, 1 on error * * Notes: * (1) Generates a pdf of contour plots of the disparity arrays. * (2) This only shows actual models; not ref models */ l_int32 dewarpaShowArrays(L_DEWARPA *dewa, l_float32 scalefact, l_int32 first, l_int32 last, const char *fontdir) { char buf[256]; char *pathname; l_int32 i, svd, shd; L_BMF *bmf; L_DEWARP *dew; PIX *pixv, *pixvs, *pixh, *pixhs, *pixt, *pixd; PIXA *pixa; PROCNAME("dewarpaShowArrays"); if (!dewa) return ERROR_INT("dew not defined", procName, 1); if (first < 0 || first > dewa->maxpage) return ERROR_INT("first out of bounds", procName, 1); if (last <= 0 || last > dewa->maxpage) last = dewa->maxpage; if (last < first) return ERROR_INT("last < first", procName, 1); lept_rmdir("lept"); lept_mkdir("lept"); if ((bmf = bmfCreate(fontdir, 8)) == NULL) L_ERROR("bmf not made; page info not displayed", procName); fprintf(stderr, "Generating contour plots\n"); for (i = first; i <= last; i++) { if (i && ((i % 10) == 0)) fprintf(stderr, " .. %d", i); dew = dewarpaGetDewarp(dewa, i); if (!dew) continue; if (dew->hasref == 1) continue; svd = shd = 0; if (dew->sampvdispar) svd = 1; if (dew->samphdispar) shd = 1; if (!svd) { L_ERROR("sampvdispar not made for page %d!\n", procName, i); continue; } /* Generate contour plots at reduced resolution */ dewarpPopulateFullRes(dew, NULL, 0, 0); pixv = fpixRenderContours(dew->fullvdispar, 3.0, 0.15); pixvs = pixScaleBySampling(pixv, scalefact, scalefact); pixDestroy(&pixv); if (shd) { pixh = fpixRenderContours(dew->fullhdispar, 3.0, 0.15); pixhs = pixScaleBySampling(pixh, scalefact, scalefact); pixDestroy(&pixh); } dewarpMinimize(dew); /* Save side-by-side */ pixa = pixaCreate(2); pixaAddPix(pixa, pixvs, L_INSERT); if (shd) pixaAddPix(pixa, pixhs, L_INSERT); pixt = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2); snprintf(buf, sizeof(buf), "Page %d", i); pixd = pixAddSingleTextblock(pixt, bmf, buf, 0x0000ff00, L_ADD_BELOW, NULL); snprintf(buf, sizeof(buf), "arrays_%04d.png", i); pathname = genPathname("/tmp/lept", buf); pixWrite(pathname, pixd, IFF_PNG); pixaDestroy(&pixa); pixDestroy(&pixt); pixDestroy(&pixd); FREE(pathname); } bmfDestroy(&bmf); fprintf(stderr, "\n"); fprintf(stderr, "Generating pdf of contour plots\n"); convertFilesToPdf("/tmp/lept", "arrays_", 90, 1.0, L_FLATE_ENCODE, 0, "Disparity arrays", "/tmp/lept/disparity_arrays.pdf"); fprintf(stderr, "Output written to: /tmp/lept/disparity_arrays.pdf\n"); return 0; }
/*! * dewarpShowResults() * * Input: dewa * sarray (of indexed input images) * boxa (crop boxes for input images; can be null) * firstpage, lastpage * fontdir (for text bitmap fonts) * pdfout (filename) * Return: 0 if OK, 1 on error * * Notes: * (1) This generates a pdf of image pairs (before, after) for * the designated set of input pages. * (2) If the boxa exists, its elements are aligned with numbers * in the filenames in @sa. It is used to crop the input images. * It is assumed that the dewa was generated from the cropped * images. No undercropping is applied before rendering. */ l_int32 dewarpShowResults(L_DEWARPA *dewa, SARRAY *sa, BOXA *boxa, l_int32 firstpage, l_int32 lastpage, const char *fontdir, const char *pdfout) { char bufstr[256]; char *outpath; l_int32 i, modelpage; L_BMF *bmf; BOX *box; L_DEWARP *dew; PIX *pixs, *pixc, *pixd, *pixt1, *pixt2; PIXA *pixa; PROCNAME("dewarpShowResults"); if (!dewa) return ERROR_INT("dewa not defined", procName, 1); if (!sa) return ERROR_INT("sa not defined", procName, 1); if (!pdfout) return ERROR_INT("pdfout not defined", procName, 1); if (firstpage > lastpage) return ERROR_INT("invalid first/last page numbers", procName, 1); lept_rmdir("dewarp_pdfout"); lept_mkdir("dewarp_pdfout"); if ((bmf = bmfCreate(fontdir, 6)) == NULL) L_ERROR("bmf not made; page info not displayed", procName); fprintf(stderr, "Dewarping and generating s/by/s view\n"); for (i = firstpage; i <= lastpage; i++) { if (i && (i % 10 == 0)) fprintf(stderr, ".. %d ", i); pixs = pixReadIndexed(sa, i); if (boxa) { box = boxaGetBox(boxa, i, L_CLONE); pixc = pixClipRectangle(pixs, box, NULL); boxDestroy(&box); } else pixc = pixClone(pixs); dew = dewarpaGetDewarp(dewa, i); pixd = NULL; if (dew) { dewarpaApplyDisparity(dewa, dew->pageno, pixc, GRAYIN_VALUE, 0, 0, &pixd, NULL); dewarpMinimize(dew); } pixa = pixaCreate(2); pixaAddPix(pixa, pixc, L_INSERT); if (pixd) pixaAddPix(pixa, pixd, L_INSERT); pixt1 = pixaDisplayTiledAndScaled(pixa, 32, 500, 2, 0, 35, 2); if (dew) { modelpage = (dew->hasref) ? dew->refpage : dew->pageno; snprintf(bufstr, sizeof(bufstr), "Page %d; using %d\n", i, modelpage); } else snprintf(bufstr, sizeof(bufstr), "Page %d; no dewarp\n", i); pixt2 = pixAddSingleTextblock(pixt1, bmf, bufstr, 0x0000ff00, L_ADD_BELOW, 0); snprintf(bufstr, sizeof(bufstr), "/tmp/dewarp_pdfout/%05d", i); pixWrite(bufstr, pixt2, IFF_JFIF_JPEG); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixt1); pixDestroy(&pixt2); } fprintf(stderr, "\n"); fprintf(stderr, "Generating pdf of result\n"); convertFilesToPdf("/tmp/dewarp_pdfout", NULL, 100, 1.0, L_JPEG_ENCODE, 0, "Dewarp sequence", pdfout); outpath = genPathname(pdfout, NULL); fprintf(stderr, "Output written to: %s\n", outpath); FREE(outpath); bmfDestroy(&bmf); return 0; }
l_int32 main(int argc, char **argv) { L_BMF *bmf; PIX *pixs1, *pixs2, *pixg, *pixt, *pixd; PIXA *pixa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; bmf = bmfCreate("./fonts", 8); pixs1 = pixCreate(301, 301, 32); pixs2 = pixCreate(601, 601, 32); pixSetAll(pixs1); pixSetAll(pixs2); pixRenderLineArb(pixs1, 0, 20, 300, 20, 5, 0, 0, 255); pixRenderLineArb(pixs1, 0, 70, 300, 70, 5, 0, 255, 0); pixRenderLineArb(pixs1, 0, 120, 300, 120, 5, 0, 255, 255); pixRenderLineArb(pixs1, 0, 170, 300, 170, 5, 255, 0, 0); pixRenderLineArb(pixs1, 0, 220, 300, 220, 5, 255, 0, 255); pixRenderLineArb(pixs1, 0, 270, 300, 270, 5, 255, 255, 0); pixRenderLineArb(pixs2, 0, 20, 300, 20, 5, 0, 0, 255); pixRenderLineArb(pixs2, 0, 70, 300, 70, 5, 0, 255, 0); pixRenderLineArb(pixs2, 0, 120, 300, 120, 5, 0, 255, 255); pixRenderLineArb(pixs2, 0, 170, 300, 170, 5, 255, 0, 0); pixRenderLineArb(pixs2, 0, 220, 300, 220, 5, 255, 0, 255); pixRenderLineArb(pixs2, 0, 270, 300, 270, 5, 255, 255, 0); /* Color, small pix */ pixa = pixaCreate(0); pixt = pixQuadraticVShear(pixs1, L_WARP_TO_LEFT, 60, -20, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "sampled-left"); pixt = pixQuadraticVShear(pixs1, L_WARP_TO_RIGHT, 60, -20, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "sampled-right"); pixt = pixQuadraticVShear(pixs1, L_WARP_TO_LEFT, 60, -20, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "interpolated-left"); pixt = pixQuadraticVShear(pixs1, L_WARP_TO_RIGHT, 60, -20, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "interpolated-right"); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_PNG); pixDisplayWithTitle(pixd, 50, 50, NULL, rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); /* Grayscale, small pix */ pixg = pixConvertTo8(pixs1, 0); pixa = pixaCreate(0); pixt = pixQuadraticVShear(pixg, L_WARP_TO_LEFT, 60, -20, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "sampled-left"); pixt = pixQuadraticVShear(pixg, L_WARP_TO_RIGHT, 60, -20, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "sampled-right"); pixt = pixQuadraticVShear(pixg, L_WARP_TO_LEFT, 60, -20, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "interpolated-left"); pixt = pixQuadraticVShear(pixg, L_WARP_TO_RIGHT, 60, -20, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "interpolated-right"); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_PNG); pixDisplayWithTitle(pixd, 250, 50, NULL, rp->display); pixDestroy(&pixg); pixDestroy(&pixd); pixaDestroy(&pixa); /* Color, larger pix */ pixa = pixaCreate(0); pixt = pixQuadraticVShear(pixs2, L_WARP_TO_LEFT, 120, -40, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "sampled-left"); pixt = pixQuadraticVShear(pixs2, L_WARP_TO_RIGHT, 120, -40, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "sampled-right"); pixt = pixQuadraticVShear(pixs2, L_WARP_TO_LEFT, 120, -40, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "interpolated-left"); pixt = pixQuadraticVShear(pixs2, L_WARP_TO_RIGHT, 120, -40, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "interpolated-right"); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_PNG); pixDisplayWithTitle(pixd, 550, 50, NULL, rp->display); pixDestroy(&pixd); pixaDestroy(&pixa); /* Grayscale, larger pix */ pixg = pixConvertTo8(pixs2, 0); pixa = pixaCreate(0); pixt = pixQuadraticVShear(pixg, L_WARP_TO_LEFT, 60, -20, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "sampled-left"); pixt = pixQuadraticVShear(pixg, L_WARP_TO_RIGHT, 60, -20, L_SAMPLED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "sampled-right"); pixt = pixQuadraticVShear(pixg, L_WARP_TO_LEFT, 60, -20, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 1, bmf, "interpolated-left"); pixt = pixQuadraticVShear(pixg, L_WARP_TO_RIGHT, 60, -20, L_INTERPOLATED, L_BRING_IN_WHITE); PixSave(&pixt, pixa, 0, bmf, "interpolated-right"); pixd = pixaDisplay(pixa, 0, 0); regTestWritePixAndCheck(rp, pixd, IFF_PNG); pixDisplayWithTitle(pixd, 850, 50, NULL, rp->display); pixDestroy(&pixg); pixDestroy(&pixd); pixaDestroy(&pixa); pixDestroy(&pixs1); pixDestroy(&pixs2); bmfDestroy(&bmf); return regTestCleanup(rp); }
main(int argc, char **argv) { char outname[256], buf[512]; l_int32 loc, i; L_BMF *bmf, *bmftop; PIX *pixs, *pixt, *pixd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8; PIXA *pixa; L_REGPARAMS *rp; SARRAY *sa; if (regTestSetup(argc, argv, &rp)) return 1; bmf = bmfCreate("./fonts", 6); bmftop = bmfCreate("./fonts", 10); pixs = pixRead("lucasta-47.jpg"); pix1 = pixScale(pixs, 0.4, 0.4); /* 8 bpp grayscale */ pix2 = pixConvertTo32(pix1); /* 32 bpp rgb */ pix3 = pixThresholdOn8bpp(pix1, 12, 1); /* 8 bpp cmapped */ pix4 = pixThresholdTo4bpp(pix1, 10, 1); /* 4 bpp cmapped */ pix5 = pixThresholdTo4bpp(pix1, 10, 0); /* 4 bpp not cmapped */ pix6 = pixThresholdTo2bpp(pix1, 3, 1); /* 2 bpp cmapped */ pix7 = pixThresholdTo2bpp(pix1, 3, 0); /* 2 bpp not cmapped */ pix8 = pixThresholdToBinary(pix1, 160); /* 1 bpp */ for (loc = 1; loc < 5; loc++) { pixa = pixaCreate(0); AddTextAndSave(pixa, pix1, bmf, textstr[0], loc, 800); AddTextAndSave(pixa, pix2, bmf, textstr[1], loc, 0xff000000); AddTextAndSave(pixa, pix3, bmf, textstr[2], loc, 0x00ff0000); AddTextAndSave(pixa, pix4, bmf, textstr[3], loc, 0x0000ff00); AddTextAndSave(pixa, pix5, bmf, textstr[4], loc, 800); AddTextAndSave(pixa, pix6, bmf, textstr[5], loc, 0xff000000); AddTextAndSave(pixa, pix7, bmf, textstr[6], loc, 800); AddTextAndSave(pixa, pix8, bmf, textstr[7], loc, 800); pixt = pixaDisplay(pixa, 0, 0); pixd = pixAddSingleTextblock(pixt, bmftop, topstr[loc - 1], 0xff00ff00, L_ADD_ABOVE, NULL); regTestWritePixAndCheck(rp, pixd, IFF_PNG); /* 0 - 4 */ pixDisplayWithTitle(pixd, 50 * loc, 50, NULL, rp->display); pixDestroy(&pixt); pixDestroy(&pixd); pixaDestroy(&pixa); } pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); pixDestroy(&pix7); pixDestroy(&pix8); bmfDestroy(&bmf); bmfDestroy(&bmftop); /* Write multiple lines in different colors, filling up * the colormap and requesting even more colors. */ pixs = pixRead("weasel4.11c.png"); pix1 = pixConvertTo8(pixs, 0); pix2 = pixScale(pixs, 8.0, 8.0); pix3 = pixQuantFromCmap(pix2, pixGetColormap(pixs), 4, 5, L_EUCLIDEAN_DISTANCE); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 5 */ pixDisplayWithTitle(pix3, 0, 500, NULL, rp->display); bmf = bmfCreate("fonts", 10); sa = sarrayCreate(6); for (i = 0; i < 6; i++) { snprintf(buf, sizeof(buf), "This is textline %d\n", i); sarrayAddString(sa, buf, L_COPY); } for (i = 0; i < 6; i++) { pixSetTextline(pix3, bmf, sarrayGetString(sa, i, L_NOCOPY), colors[i], 50, 120 + 60 * i, NULL, NULL); } regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 6 */ pixDisplayWithTitle(pix3, 600, 500, NULL, rp->display); pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); bmfDestroy(&bmf); sarrayDestroy(&sa); return regTestCleanup(rp); }
main(int argc, char **argv) { char outname[256]; l_int32 loc, display, success; L_BMF *bmf, *bmftop; FILE *fp; PIX *pixs, *pixt, *pixd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8; PIXA *pixa; if (regTestSetup(argc, argv, &fp, &display, &success, NULL)) return 1; bmf = bmfCreate("./fonts", 6); bmftop = bmfCreate("./fonts", 10); pixs = pixRead("lucasta-47.jpg"); pix1 = pixScale(pixs, 0.4, 0.4); /* 8 bpp grayscale */ pix2 = pixConvertTo32(pix1); /* 32 bpp rgb */ pix3 = pixThresholdOn8bpp(pix1, 12, 1); /* 8 bpp cmapped */ pix4 = pixThresholdTo4bpp(pix1, 10, 1); /* 4 bpp cmapped */ pix5 = pixThresholdTo4bpp(pix1, 10, 0); /* 4 bpp not cmapped */ pix6 = pixThresholdTo2bpp(pix1, 3, 1); /* 2 bpp cmapped */ pix7 = pixThresholdTo2bpp(pix1, 3, 0); /* 2 bpp not cmapped */ pix8 = pixThresholdToBinary(pix1, 160); /* 1 bpp */ for (loc = 1; loc < 5; loc++) { pixa = pixaCreate(0); AddTextAndSave(pixa, pix1, bmf, textstr[0], loc, 190); AddTextAndSave(pixa, pix2, bmf, textstr[1], loc, 0xff000000); AddTextAndSave(pixa, pix3, bmf, textstr[2], loc, 0x00ff0000); AddTextAndSave(pixa, pix4, bmf, textstr[3], loc, 0x0000ff00); AddTextAndSave(pixa, pix5, bmf, textstr[4], loc, 11); AddTextAndSave(pixa, pix6, bmf, textstr[5], loc, 0xff000000); AddTextAndSave(pixa, pix7, bmf, textstr[6], loc, 2); AddTextAndSave(pixa, pix8, bmf, textstr[7], loc, 1); pixt = pixaDisplay(pixa, 0, 0); pixd = pixAddSingleTextblock(pixt, bmftop, topstr[loc - 1], 0xff00ff00, L_ADD_ABOVE, NULL); snprintf(outname, 240, "/tmp/writetext.%d.png", loc - 1); pixWrite(outname, pixd, IFF_PNG); regTestCheckFile(fp, argv, outname, loc - 1, &success); pixDisplayWithTitle(pixd, 50 * loc, 50, NULL, display); pixDestroy(&pixt); pixDestroy(&pixd); pixaDestroy(&pixa); } pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); pixDestroy(&pix7); pixDestroy(&pix8); bmfDestroy(&bmf); bmfDestroy(&bmftop); regTestCleanup(argc, argv, fp, success, NULL); return 0; }
int main(int argc, char **argv) { char textstr[256]; l_int32 i, thresh, fgval, bgval; l_float32 scorefract; L_BMF *bmf; PIX *pixs, *pixb, *pixb2, *pixb3, *pixg, *pixp, *pixt1, *pixt2; PIXA *pixa; pixs = pixRead("1555-7.jpg"); pixg = pixConvertTo8(pixs, 0); bmf = bmfCreate("fonts", 8); for (i = 0; i < 3; i++) { pixa = pixaCreate(3); scorefract = 0.1 * i; pixOtsuAdaptiveThreshold(pixg, 2000, 2000, 0, 0, scorefract, NULL, &pixb); pixSaveTiledOutline(pixb, pixa, 0.5, 1, 20, 2, 32); pixSplitDistributionFgBg(pixg, scorefract, 1, &thresh, &fgval, &bgval, 1); fprintf(stderr, "thresh = %d, fgval = %d, bgval = %d\n", thresh, fgval, bgval); /* Give gnuplot time to write out the plot */ #ifndef _WIN32 sleep(1); #else Sleep(1000); #endif /* _WIN32 */ pixp = pixRead("/tmp/histplot.png"); pixSaveTiled(pixp, pixa, 1.0, 0, 20, 1); pixt1 = pixaDisplay(pixa, 0, 0); snprintf(textstr, sizeof(textstr), "Scorefract = %3.1f ........... Thresh = %d", scorefract, thresh); pixt2 = pixAddSingleTextblock(pixt1, bmf, textstr, 0x00ff0000, L_ADD_BELOW, NULL); pixDisplay(pixt2, 100, 100); snprintf(textstr, sizeof(textstr), "/tmp/otsu.%d.png", i); pixWrite(textstr, pixt2, IFF_PNG); pixDestroy(&pixb); pixDestroy(&pixp); pixDestroy(&pixt1); pixDestroy(&pixt2); pixaDestroy(&pixa); } pixa = pixaCreate(2); for (i = 0; i < 2; i++) { scorefract = 0.1 * i; pixOtsuAdaptiveThreshold(pixg, 300, 300, 0, 0, scorefract, NULL, &pixb); pixb2 = pixAddBlackOrWhiteBorder(pixb, 2, 2, 2, 2, L_GET_BLACK_VAL); snprintf(textstr, sizeof(textstr), "Scorefract = %3.1f", scorefract); pixb3 = pixAddSingleTextblock(pixb2, bmf, textstr, 1, L_ADD_BELOW, NULL); pixSaveTiled(pixb3, pixa, 2, (i + 1) % 1, 20, 32); pixDestroy(&pixb); pixDestroy(&pixb2); } pixb = pixaDisplay(pixa, 0, 0); pixWrite("/tmp/otsu-tiled.jpg", pixb, IFF_PNG); pixDestroy(&pixb); pixaDestroy(&pixa); bmfDestroy(&bmf); pixDestroy(&pixs); pixDestroy(&pixg); return 0; }
l_int32 main(int argc, char **argv) { l_int32 size, i, rval, gval, bval, yval, uval, vval; l_float32 *a[3], b[3]; L_BMF *bmf; PIX *pixd; PIXA *pixa; /* Explore the range of rgb --> yuv transforms. All rgb * values transform to a valid value of yuv, so when transforming * back we get the same rgb values that we started with. */ pixa = pixaCreate(0); bmf = bmfCreate("fonts", 6); for (gval = 0; gval <= 255; gval += 20) AddTransformsRGB(pixa, bmf, gval); pixd = pixaDisplayTiledAndScaled(pixa, 32, 755, 1, 0, 20, 2); pixDisplay(pixd, 100, 0); pixWrite("/tmp/yuv1.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); /* Now start with all "valid" yuv values, not all of which are * related to a valid rgb value. Our yuv --> rgb transform * clips the rgb components to [0 ... 255], so when transforming * back we get different values whenever the initial yuv * value is out of the rgb gamut. */ pixa = pixaCreate(0); for (yval = 16; yval <= 235; yval += 16) AddTransformsYUV(pixa, bmf, yval); pixd = pixaDisplayTiledAndScaled(pixa, 32, 755, 1, 0, 20, 2); pixDisplay(pixd, 600, 0); pixWrite("/tmp/yuv2.png", pixd, IFF_PNG); pixDestroy(&pixd); pixaDestroy(&pixa); bmfDestroy(&bmf); /* --------- Try out a special case by hand, and show that --------- * * ------- the transform matrices we are using are inverses ---------*/ /* First, use our functions for the transform */ fprintf(stderr, "Start with: yval = 143, uval = 79, vval = 103\n"); convertYUVToRGB(143, 79, 103, &rval, &gval, &bval); fprintf(stderr, " ==> rval = %d, gval = %d, bval = %d\n", rval, gval, bval); convertRGBToYUV(rval, gval, bval, &yval, &uval, &vval); fprintf(stderr, " ==> yval = %d, uval = %d, vval = %d\n", yval, uval, vval); /* Next, convert yuv --> rbg by solving for rgb --> yuv transform. * [ a00 a01 a02 ] r = b0 (y - 16) * [ a10 a11 a12 ] * g = b1 (u - 128) * [ a20 a21 a22 ] b = b2 (v - 128) */ b[0] = 143.0 - 16.0; /* y - 16 */ b[1] = 79.0 - 128.0; /* u - 128 */ b[2] = 103.0 - 128.0; /* v - 128 */ for (i = 0; i < 3; i++) a[i] = (l_float32 *)lept_calloc(3, sizeof(l_float32)); a[0][0] = 65.738 / 256.0; a[0][1] = 129.057 / 256.0; a[0][2] = 25.064 / 256.0; a[1][0] = -37.945 / 256.0; a[1][1] = -74.494 / 256.0; a[1][2] = 112.439 / 256.0; a[2][0] = 112.439 / 256.0; a[2][1] = -94.154 / 256.0; a[2][2] = -18.285 / 256.0; fprintf(stderr, "Here's the original matrix: yuv --> rgb:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); gaussjordan(a, b, 3); fprintf(stderr, "\nInput (yuv) = (143,79,103); solve for rgb:\n" "rval = %7.3f, gval = %7.3f, bval = %7.3f\n", b[0], b[1], b[2]); fprintf(stderr, "Here's the inverse matrix: rgb --> yuv:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); /* Now, convert back: rgb --> yuv; * Do this by solving for yuv --> rgb transform. * Use the b[] found previously (the rgb values), and * the a[][] which now holds the rgb --> yuv transform. */ gaussjordan(a, b, 3); fprintf(stderr, "\nInput rgb; solve for yuv:\n" "yval = %7.3f, uval = %7.3f, vval = %7.3f\n", b[0] + 16.0, b[1] + 128.0, b[2] + 128.0); fprintf(stderr, "Inverting the matrix again: yuv --> rgb:\n"); for (i = 0; i < 3; i++) fprintf(stderr, " %7.3f %7.3f %7.3f\n", 256.0 * a[i][0], 256.0 * a[i][1], 256.0 * a[i][2]); for (i = 0; i < 3; i++) lept_free(a[i]); return 0; }
/*! * \brief boxaDisplayTiled() * * \param[in] boxas * \param[in] pixa [optional] background for each box * \param[in] first index of first box * \param[in] last index of last box; use -1 to go to end * \param[in] maxwidth of output image * \param[in] linewidth width of box outlines, before scaling * \param[in] scalefactor applied to every box; use 1.0 for no scaling * \param[in] background 0 for white, 1 for black; this is the color * of the spacing between the images * \param[in] spacing between images, and on outside * \param[in] border width of black border added to each image; * use 0 for no border * \return pixd of tiled images of boxes, or NULL on error * * <pre> * Notes: * (1) Displays each box separately in a tiled 32 bpp image. * (2) If pixa is defined, it must have the same count as the boxa, * and it will be a background over with each box is rendered. * If pixa is not defined, the boxes will be rendered over * blank images of identical size. * (3) See pixaDisplayTiledInRows() for other parameters. * </pre> */ PIX * boxaDisplayTiled(BOXA *boxas, PIXA *pixa, l_int32 first, l_int32 last, l_int32 maxwidth, l_int32 linewidth, l_float32 scalefactor, l_int32 background, l_int32 spacing, l_int32 border) { char buf[32]; l_int32 i, n, npix, w, h, fontsize; L_BMF *bmf; BOX *box; BOXA *boxa; PIX *pix1, *pix2, *pixd; PIXA *pixat; PROCNAME("boxaDisplayTiled"); if (!boxas) return (PIX *)ERROR_PTR("boxas not defined", procName, NULL); boxa = boxaSaveValid(boxas, L_COPY); n = boxaGetCount(boxa); if (pixa) { npix = pixaGetCount(pixa); if (n != npix) { boxaDestroy(&boxa); return (PIX *)ERROR_PTR("boxa and pixa counts differ", procName, NULL); } } first = L_MAX(0, first); if (last < 0) last = n - 1; if (first >= n) { boxaDestroy(&boxa); return (PIX *)ERROR_PTR("invalid first", procName, NULL); } if (last >= n) { L_WARNING("last = %d is beyond max index = %d; adjusting\n", procName, last, n - 1); last = n - 1; } if (first > last) { boxaDestroy(&boxa); return (PIX *)ERROR_PTR("first > last", procName, NULL); } /* Because the bitmap font will be reduced when tiled, choose the * font size inversely with the scale factor. */ if (scalefactor > 0.8) fontsize = 6; else if (scalefactor > 0.6) fontsize = 10; else if (scalefactor > 0.4) fontsize = 14; else if (scalefactor > 0.3) fontsize = 18; else fontsize = 20; bmf = bmfCreate(NULL, fontsize); pixat = pixaCreate(n); boxaGetExtent(boxa, &w, &h, NULL); for (i = first; i <= last; i++) { box = boxaGetBox(boxa, i, L_CLONE); if (!pixa) { pix1 = pixCreate(w, h, 32); pixSetAll(pix1); } else { pix1 = pixaGetPix(pixa, i, L_COPY); } pixSetBorderVal(pix1, 0, 0, 0, 2, 0x0000ff00); snprintf(buf, sizeof(buf), "%d", i); pix2 = pixAddSingleTextblock(pix1, bmf, buf, 0x00ff0000, L_ADD_BELOW, NULL); pixDestroy(&pix1); pixRenderBoxArb(pix2, box, linewidth, 255, 0, 0); pixaAddPix(pixat, pix2, L_INSERT); boxDestroy(&box); } bmfDestroy(&bmf); boxaDestroy(&boxa); pixd = pixaDisplayTiledInRows(pixat, 32, maxwidth, scalefactor, background, spacing, border); pixaDestroy(&pixat); return pixd; }
l_int32 main(int argc, char **argv) { char buf[512]; l_int32 i, n, index; l_int32 rval[4], gval[4], bval[4]; l_uint32 scolor, dcolor; L_BMF *bmf; PIX *pix0, *pix1, *pix2, *pix3, *pix4, *pix5; PIXA *pixa; PIXCMAP *cmap; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* Read in the bg colors */ for (i = 0; i < 4; i++) sscanf(bgcolors[i], "%d %d %d", &rval[i], &gval[i], &bval[i]); bmf = bmfCreate("fonts", 8); /* Get the input image (100 ppi resolution) */ pix0 = pixRead("harmoniam100-11.png"); cmap = pixGetColormap(pix0); pixa = pixaCreate(0); /* Do cmapped coloring on the white pixels only */ pixcmapGetIndex(cmap, 255, 255, 255, &index); /* index of white pixels */ for (i = 0; i < 4; i++) { pixcmapResetColor(cmap, index, rval[i], gval[i], bval[i]); snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)", rval[i], gval[i], bval[i]); pix1 = pixAddSingleTextblock(pix0, bmf, buf, 0xff000000, L_ADD_AT_BOT, NULL); pixaAddPix(pixa, pix1, L_INSERT); } /* Do cmapped background coloring on all the pixels */ for (i = 0; i < 4; i++) { scolor = 0xffffff00; /* source color */ composeRGBPixel(rval[i], gval[i], bval[i], &dcolor); /* dest color */ pix1 = pixShiftByComponent(NULL, pix0, scolor, dcolor); snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)", rval[i], gval[i], bval[i]); pix2 = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000, L_ADD_AT_BOT, NULL); pixaAddPix(pixa, pix2, L_INSERT); pixDestroy(&pix1); } /* Do background coloring on rgb */ pix1 = pixConvertTo32(pix0); for (i = 0; i < 4; i++) { scolor = 0xffffff00; composeRGBPixel(rval[i], gval[i], bval[i], &dcolor); pix2 = pixShiftByComponent(NULL, pix1, scolor, dcolor); snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)", rval[i], gval[i], bval[i]); pix3 = pixAddSingleTextblock(pix2, bmf, buf, 0xff000000, L_ADD_AT_BOT, NULL); pixaAddPix(pixa, pix3, L_INSERT); pixDestroy(&pix2); } pixDestroy(&pix1); /* Compare cmapped & rgb foreground coloring */ scolor = 0x0; /* source color */ composeRGBPixel(200, 30, 150, &dcolor); /* ugly fg dest color */ pix1 = pixShiftByComponent(NULL, pix0, scolor, dcolor); /* cmapped */ snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)", 200, 100, 50); pix2 = pixAddSingleTextblock(pix1, bmf, buf, 0xff000000, L_ADD_AT_BOT, NULL); pixaAddPix(pixa, pix2, L_INSERT); pix3 = pixConvertTo32(pix0); pix4 = pixShiftByComponent(NULL, pix3, scolor, dcolor); /* rgb */ snprintf(buf, sizeof(buf), "(rval, bval, gval) = (%d, %d, %d)", 200, 100, 50); pix5 = pixAddSingleTextblock(pix4, bmf, buf, 0xff000000, L_ADD_AT_BOT, NULL); pixaAddPix(pixa, pix5, L_INSERT); regTestComparePix(rp, pix1, pix4); regTestComparePix(rp, pix2, pix5); pixDestroy(&pix1); pixDestroy(&pix3); pixDestroy(&pix4); /* Log all the results */ n = pixaGetCount(pixa); for (i = 0; i < n; i++) { pix1 = pixaGetPix(pixa, i, L_CLONE); regTestWritePixAndCheck(rp, pix1, IFF_PNG); pixDestroy(&pix1); } /* If in testing mode, make a pdf */ if (rp->display) { pixaConvertToPdf(pixa, 100, 1.0, L_FLATE_ENCODE, 0, "Colored background", "/tmp/regout/coloring.pdf"); L_INFO("Output pdf: /tmp/regout/coloring.pdf\n", rp->testname); } pixaDestroy(&pixa); pixDestroy(&pix0); bmfDestroy(&bmf); return regTestCleanup(rp); }
l_int32 main(int argc, char **argv) { l_int32 irval, igval, ibval; l_float32 rval, gval, bval, fract, fgfract; L_BMF *bmf; BOX *box; BOXA *boxa; FPIX *fpix; PIX *pixs, *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7; PIX *pix8, *pix9, *pix10, *pix11, *pix12, *pix13, *pix14, *pix15; PIXA *pixa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; pixa = pixaCreate(0); pixs = pixRead("breviar38.150.jpg"); /* pixs = pixRead("breviar32.150.jpg"); */ pixaAddPix(pixa, pixs, L_CLONE); regTestWritePixAndCheck(rp, pixs, IFF_JFIF_JPEG); /* 0 */ pixDisplayWithTitle(pixs, 0, 0, "Input image", rp->display); /* Extract the blue component, which is small in all the text * regions, including in the highlight color region */ pix1 = pixGetRGBComponent(pixs, COLOR_BLUE); pixaAddPix(pixa, pix1, L_CLONE); regTestWritePixAndCheck(rp, pix1, IFF_JFIF_JPEG); /* 1 */ pixDisplayWithTitle(pix1, 200, 0, "Blue component", rp->display); /* Do a background normalization, with the background set to * approximately 200 */ pix2 = pixBackgroundNormSimple(pix1, NULL, NULL); pixaAddPix(pixa, pix2, L_COPY); regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG); /* 2 */ pixDisplayWithTitle(pix2, 400, 0, "BG normalized to 200", rp->display); /* Do a linear transform on the gray pixels, with 50 going to * black and 160 going to white. 50 is sufficiently low to * make both the red and black print quite dark. Quantize * to a few equally spaced gray levels. This is the image * to which highlight color will be applied. */ pixGammaTRC(pix2, pix2, 1.0, 50, 160); pix3 = pixThresholdOn8bpp(pix2, 7, 1); pixaAddPix(pixa, pix3, L_CLONE); regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG); /* 3 */ pixDisplayWithTitle(pix3, 600, 0, "Basic quantized with white bg", rp->display); /* Identify the regions of red text. First, make a mask * consisting of all pixels such that (R-B)/B is larger * than 2.0. This will have all the red, plus a lot of * the dark pixels. */ fpix = pixComponentFunction(pixs, 1.0, 0.0, -1.0, 0.0, 0.0, 1.0); pix4 = fpixThresholdToPix(fpix, 2.0); pixInvert(pix4, pix4); /* red plus some dark text */ pixaAddPix(pixa, pix4, L_CLONE); regTestWritePixAndCheck(rp, pix4, IFF_PNG); /* 4 */ pixDisplayWithTitle(pix4, 800, 0, "Red plus dark pixels", rp->display); /* Make a mask consisting of all the red and background pixels */ pix5 = pixGetRGBComponent(pixs, COLOR_RED); pix6 = pixThresholdToBinary(pix5, 128); pixInvert(pix6, pix6); /* red plus background (white) */ /* Intersect the two masks to get a mask consisting of pixels * that are almost certainly red. This is the seed. */ pix7 = pixAnd(NULL, pix4, pix6); /* red only (seed) */ pixaAddPix(pixa, pix7, L_COPY); regTestWritePixAndCheck(rp, pix7, IFF_PNG); /* 5 */ pixDisplayWithTitle(pix7, 0, 600, "Seed for red color", rp->display); /* Make the clipping mask by thresholding the image with * the background cleaned to white. */ pix8 = pixThresholdToBinary(pix2, 230); /* mask */ pixaAddPix(pixa, pix8, L_CLONE); regTestWritePixAndCheck(rp, pix8, IFF_PNG); /* 6 */ pixDisplayWithTitle(pix8, 200, 600, "Clipping mask for red components", rp->display); /* Fill into the mask from the seed */ pixSeedfillBinary(pix7, pix7, pix8, 8); /* filled: red plus touching */ regTestWritePixAndCheck(rp, pix7, IFF_PNG); /* 7 */ pixDisplayWithTitle(pix7, 400, 600, "Red component mask filled", rp->display); /* Remove long horizontal and vertical lines from the filled result */ pix9 = pixMorphSequence(pix7, "o40.1", 0); pixSubtract(pix7, pix7, pix9); /* remove long horizontal lines */ pixDestroy(&pix9); pix9 = pixMorphSequence(pix7, "o1.40", 0); pixSubtract(pix7, pix7, pix9); /* remove long vertical lines */ /* Close the regions to be colored */ pix10 = pixMorphSequence(pix7, "c5.1", 0); pixaAddPix(pixa, pix10, L_CLONE); regTestWritePixAndCheck(rp, pix10, IFF_PNG); /* 8 */ pixDisplayWithTitle(pix10, 600, 600, "Components defining regions allowing coloring", rp->display); /* Sanity check on amount to be colored. Only accept images * with less than 10% of all the pixels with highlight color */ pixForegroundFraction(pix10, &fgfract); if (fgfract >= 0.10) { L_INFO("too much highlighting: fract = %6.3f; removing it\n", rp->testname, fgfract); pixClearAll(pix10); pixSetPixel(pix10, 0, 0, 1); } /* Get the bounding boxes of the regions to be colored */ boxa = pixConnCompBB(pix10, 8); /* Get a color to paint that is representative of the * actual highlight color in the image. Scale each * color component up from the average by an amount necessary * to saturate the red. Then divide the green and * blue components by 2.0. */ pixGetAverageMaskedRGB(pixs, pix7, 0, 0, 1, L_MEAN_ABSVAL, &rval, &gval, &bval); fract = 255.0 / rval; irval = lept_roundftoi(fract * rval); igval = lept_roundftoi(fract * gval / 2.0); ibval = lept_roundftoi(fract * bval / 2.0); fprintf(stderr, "(r,g,b) = (%d,%d,%d)\n", irval, igval, ibval); /* Color the quantized gray version in the selected regions */ pix11 = pixColorGrayRegions(pix3, boxa, L_PAINT_DARK, 220, irval, igval, ibval); pixaAddPix(pixa, pix11, L_CLONE); regTestWritePixAndCheck(rp, pix11, IFF_PNG); /* 9 */ pixDisplayWithTitle(pix11, 800, 600, "Final colored result", rp->display); pixaAddPix(pixa, pixs, L_CLONE); /* Test colorization on gray and cmapped gray */ pix12 = pixColorGrayRegions(pix2, boxa, L_PAINT_DARK, 220, 0, 255, 0); pixaAddPix(pixa, pix12, L_CLONE); regTestWritePixAndCheck(rp, pix12, IFF_PNG); /* 10 */ pixDisplayWithTitle(pix12, 900, 600, "Colorizing boxa gray", rp->display); box = boxCreate(200, 200, 250, 350); pix13 = pixCopy(NULL, pix2); pixColorGray(pix13, box, L_PAINT_DARK, 220, 0, 0, 255); pixaAddPix(pixa, pix13, L_CLONE); regTestWritePixAndCheck(rp, pix13, IFF_PNG); /* 11 */ pixDisplayWithTitle(pix13, 1000, 600, "Colorizing box gray", rp->display); pix14 = pixThresholdTo4bpp(pix2, 6, 1); pix15 = pixColorGrayRegions(pix14, boxa, L_PAINT_DARK, 220, 0, 0, 255); pixaAddPix(pixa, pix15, L_CLONE); regTestWritePixAndCheck(rp, pix15, IFF_PNG); /* 12 */ pixDisplayWithTitle(pix15, 1100, 600, "Colorizing boxa cmap", rp->display); pixColorGrayCmap(pix14, box, L_PAINT_DARK, 0, 255, 255); pixaAddPix(pixa, pix14, L_CLONE); regTestWritePixAndCheck(rp, pix14, IFF_PNG); /* 13 */ pixDisplayWithTitle(pix14, 1200, 600, "Colorizing box cmap", rp->display); boxDestroy(&box); /* Generate a pdf of the intermediate results */ lept_mkdir("lept"); L_INFO("Writing to /tmp/lept/colorize.pdf\n", rp->testname); pixaConvertToPdf(pixa, 90, 1.0, 0, 0, "Colorizing highlighted text", "/tmp/lept/colorize.pdf"); pixaDestroy(&pixa); fpixDestroy(&fpix); boxDestroy(&box); boxaDestroy(&boxa); pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); pixDestroy(&pix7); pixDestroy(&pix8); pixDestroy(&pix9); pixDestroy(&pix10); pixDestroy(&pix11); pixDestroy(&pix12); pixDestroy(&pix13); pixDestroy(&pix14); pixDestroy(&pix15); /* Test the color detector */ pixa = pixaCreate(7); bmf = bmfCreate("./fonts", 4); pix1 = TestForRedColor(rp, "brev06.75.jpg", 1, bmf); /* 14 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = TestForRedColor(rp, "brev10.75.jpg", 0, bmf); /* 15 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = TestForRedColor(rp, "brev14.75.jpg", 1, bmf); /* 16 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = TestForRedColor(rp, "brev20.75.jpg", 1, bmf); /* 17 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = TestForRedColor(rp, "brev36.75.jpg", 0, bmf); /* 18 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = TestForRedColor(rp, "brev53.75.jpg", 1, bmf); /* 19 */ pixaAddPix(pixa, pix1, L_INSERT); pix1 = TestForRedColor(rp, "brev56.75.jpg", 1, bmf); /* 20 */ pixaAddPix(pixa, pix1, L_INSERT); /* Generate a pdf of the color detector results */ L_INFO("Writing to /tmp/lept/colordetect.pdf\n", rp->testname); pixaConvertToPdf(pixa, 45, 1.0, 0, 0, "Color detection", "/tmp/lept/colordetect.pdf"); pixaDestroy(&pixa); bmfDestroy(&bmf); return regTestCleanup(rp); }
int main(int argc, char **argv) { char buf[32]; char *filein, *fileout, *fontdir, *textstr; l_int32 n, i, maxdepth, ntext, border, lossless, display, showtext; l_float32 scalefact; L_BMF *bmf; PIX *pix1, *pix2, *pix3, *pix4, *pixd; PIXA *pixa, *pixad; static char mainName[] = "displaypixa"; if (argc != 3 && argc != 4 && argc != 7 && argc != 8) { fprintf(stderr, "Syntax error in displaypixa:\n" " displaypixa filein fileout [showtext]\n" " displaypixa filein scalefact border" " lossless disp fileout [showtext]\n"); return 1; } filein = argv[1]; if ((pixa = pixaRead(filein)) == NULL) return ERROR_INT("pixa not made", mainName, 1); pixaCountText(pixa, &ntext); if (argc == 3 || argc == 4) fileout = argv[2]; if (argc == 4) showtext = atoi(argv[3]); /* Simple specification; no output text */ if (argc == 3 || (argc == 4 && (ntext == 0 || showtext == 0))) { /* no text output */ pixaVerifyDepth(pixa, &maxdepth); pixd = pixaDisplayTiledInRows(pixa, maxdepth, 1400, 1.0, 0, 10, 0); pixDisplay(pixd, 100, 100); if (pixGetDepth(pixd) == 1) pixWrite(fileout, pixd, IFF_PNG); else pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); return 0; } /* Simple specification with output text */ if (argc == 4) { /* showtext == 1 && ntext > 0 */ n = pixaGetCount(pixa); bmf = bmfCreate(NULL, 6); pixad = pixaCreate(n); for (i = 0; i < n; i++) { pix1 = pixaGetPix(pixa, i, L_CLONE); pix2 = pixConvertTo32(pix1); pix3 = pixAddBorderGeneral(pix2, 10, 10, 5, 5, 0xffffff00); textstr = pixGetText(pix1); if (textstr && strlen(textstr) > 0) { snprintf(buf, sizeof(buf), "%s", textstr); pix4 = pixAddSingleTextblock(pix3, bmf, buf, 0xff000000, L_ADD_BELOW, NULL); } else { pix4 = pixClone(pix3); } pixaAddPix(pixad, pix4, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); } bmfDestroy(&bmf); pixaVerifyDepth(pixad, &maxdepth); pixd = pixaDisplayTiledInRows(pixad, maxdepth, 1400, 1.0, 0, 10, 0); pixDisplay(pixd, 100, 100); if (pixGetDepth(pixd) == 1) pixWrite(fileout, pixd, IFF_PNG); else pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixaDestroy(&pixad); return 0; } /* Full specification */ scalefact = atof(argv[2]); border = atoi(argv[3]); lossless = atoi(argv[4]); display = atoi(argv[5]); fileout = argv[6]; showtext = (argc == 8) ? atoi(argv[7]) : 0; if (showtext && ntext == 0) L_INFO("No text found in any of the pix\n", mainName); bmf = (showtext && ntext > 0) ? bmfCreate(NULL, 6) : NULL; n = pixaGetCount(pixa); pixad = pixaCreate(n); for (i = 0; i < n; i++) { pix1 = pixaGetPix(pixa, i, L_CLONE); pix2 = pixConvertTo32(pix1); pix3 = pixAddBorderGeneral(pix2, 10, 10, 5, 5, 0xffffff00); textstr = pixGetText(pix1); if (bmf && textstr && strlen(textstr) > 0) { snprintf(buf, sizeof(buf), "%s", textstr); pix4 = pixAddSingleTextblock(pix3, bmf, buf, 0xff000000, L_ADD_BELOW, NULL); } else { pix4 = pixClone(pix3); } pixaAddPix(pixad, pix4, L_INSERT); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); } bmfDestroy(&bmf); pixaVerifyDepth(pixad, &maxdepth); pixd = pixaDisplayTiledInRows(pixad, maxdepth, 1400, scalefact, 0, 10, border); if (display) pixDisplay(pixd, 20, 20); if (pixGetDepth(pixd) == 1 || lossless) pixWrite(fileout, pixd, IFF_PNG); else pixWrite(fileout, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixaDestroy(&pixa); pixaDestroy(&pixad); return 0; }
main(int argc, char **argv) { l_float32 scalefact; L_BMF *bmf, *bmftop; L_KERNEL *kel, *kelx, *kely; PIX *pixs, *pixg, *pixt, *pixd; PIX *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7, *pix8; PIXA *pixa; L_REGPARAMS *rp; if (regTestSetup(argc, argv, &rp)) return 1; /* ----------------- Test on 8 bpp grayscale ---------------------*/ pixa = pixaCreate(5); bmf = bmfCreate("./fonts", 6); bmftop = bmfCreate("./fonts", 10); pixs = pixRead("lucasta-47.jpg"); pixg = pixScale(pixs, 0.4, 0.4); /* 8 bpp grayscale */ pix1 = pixConvertTo32(pixg); /* 32 bpp rgb */ AddTextAndSave(pixa, pix1, 1, bmf, textstr[0], L_ADD_BELOW, 0xff000000); pix2 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_RGB); AddTextAndSave(pixa, pix2, 0, bmf, textstr[1], L_ADD_BELOW, 0x00ff0000); pix3 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_BGR); AddTextAndSave(pixa, pix3, 0, bmf, textstr[2], L_ADD_BELOW, 0x0000ff00); pix4 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_VRGB); AddTextAndSave(pixa, pix4, 0, bmf, textstr[3], L_ADD_BELOW, 0x00ff0000); pix5 = pixConvertGrayToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_VBGR); AddTextAndSave(pixa, pix5, 0, bmf, textstr[4], L_ADD_BELOW, 0x0000ff00); pixt = pixaDisplay(pixa, 0, 0); pixd = pixAddSingleTextblock(pixt, bmftop, "Regression test for subpixel scaling: gray", 0xff00ff00, L_ADD_ABOVE, NULL); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 0 */ pixDisplayWithTitle(pixd, 50, 50, NULL, rp->display); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixg); pixDestroy(&pixt); pixDestroy(&pixd); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); /* ----------------- Test on 32 bpp rgb ---------------------*/ pixa = pixaCreate(5); pixs = pixRead("fish24.jpg"); pix1 = pixScale(pixs, 0.4, 0.4); AddTextAndSave(pixa, pix1, 1, bmf, textstr[0], L_ADD_BELOW, 0xff000000); pix2 = pixConvertToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_RGB); AddTextAndSave(pixa, pix2, 0, bmf, textstr[1], L_ADD_BELOW, 0x00ff0000); pix3 = pixConvertToSubpixelRGB(pixs, 0.4, 0.35, L_SUBPIXEL_ORDER_BGR); AddTextAndSave(pixa, pix3, 0, bmf, textstr[2], L_ADD_BELOW, 0x0000ff00); pix4 = pixConvertToSubpixelRGB(pixs, 0.4, 0.45, L_SUBPIXEL_ORDER_VRGB); AddTextAndSave(pixa, pix4, 0, bmf, textstr[3], L_ADD_BELOW, 0x00ff0000); pix5 = pixConvertToSubpixelRGB(pixs, 0.4, 0.4, L_SUBPIXEL_ORDER_VBGR); AddTextAndSave(pixa, pix5, 0, bmf, textstr[4], L_ADD_BELOW, 0x0000ff00); pixt = pixaDisplay(pixa, 0, 0); pixd = pixAddSingleTextblock(pixt, bmftop, "Regression test for subpixel scaling: color", 0xff00ff00, L_ADD_ABOVE, NULL); regTestWritePixAndCheck(rp, pixd, IFF_JFIF_JPEG); /* 1 */ pixDisplayWithTitle(pixd, 50, 350, NULL, rp->display); pixaDestroy(&pixa); pixDestroy(&pixs); pixDestroy(&pixt); pixDestroy(&pixd); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); bmfDestroy(&bmf); bmfDestroy(&bmftop); /* --------------- Test on images that are initially 1 bpp ------------*/ /* For these, it is better to apply a lowpass filter before scaling */ /* Normal scaling of 8 bpp grayscale */ scalefact = 800. / 2320.; pixs = pixRead("patent.png"); /* sharp, 300 ppi, 1 bpp image */ pix1 = pixConvertTo8(pixs, FALSE); /* use 8 bpp input */ pix2 = pixScale(pix1, scalefact, scalefact); regTestWritePixAndCheck(rp, pix2, IFF_PNG); /* 2 */ /* Subpixel scaling; bad because there is very little aliasing. */ pix3 = pixConvertToSubpixelRGB(pix1, scalefact, scalefact, L_SUBPIXEL_ORDER_RGB); regTestWritePixAndCheck(rp, pix3, IFF_PNG); /* 3 */ /* Get same (bad) result doing subpixel rendering on RGB input */ pix4 = pixConvertTo32(pixs); pix5 = pixConvertToSubpixelRGB(pix4, scalefact, scalefact, L_SUBPIXEL_ORDER_RGB); regTestComparePix(rp, pix3, pix5); /* 4 */ regTestWritePixAndCheck(rp, pix5, IFF_PNG); /* 5 */ /* Now apply a small lowpass filter before scaling. */ makeGaussianKernelSep(2, 2, 1.0, 1.0, &kelx, &kely); startTimer(); pix6 = pixConvolveSep(pix1, kelx, kely, 8, 1); /* normalized */ fprintf(stderr, "Time sep: %7.3f\n", stopTimer()); regTestWritePixAndCheck(rp, pix6, IFF_PNG); /* 6 */ /* Get same lowpass result with non-separated convolution */ kel = makeGaussianKernel(2, 2, 1.0, 1.0); startTimer(); pix7 = pixConvolve(pix1, kel, 8, 1); /* normalized */ fprintf(stderr, "Time non-sep: %7.3f\n", stopTimer()); regTestComparePix(rp, pix6, pix7); /* 7 */ /* Now do the subpixel scaling on this slightly blurred image */ pix8 = pixConvertToSubpixelRGB(pix6, scalefact, scalefact, L_SUBPIXEL_ORDER_RGB); regTestWritePixAndCheck(rp, pix8, IFF_PNG); /* 8 */ kernelDestroy(&kelx); kernelDestroy(&kely); kernelDestroy(&kel); pixDestroy(&pixs); pixDestroy(&pix1); pixDestroy(&pix2); pixDestroy(&pix3); pixDestroy(&pix4); pixDestroy(&pix5); pixDestroy(&pix6); pixDestroy(&pix7); pixDestroy(&pix8); return regTestCleanup(rp); }
main(int argc, char **argv) { char buf[256]; l_int32 w, h, i, j, k, index, op, dir, stretch; l_float32 del, angle, angledeg; BOX *box; L_BMF *bmf; PIX *pixs, *pixt, *pixt2, *pixd; static char mainName[] = "warpertest"; if (argc != 1) exit(ERROR_INT("syntax: warpertest", mainName, 1)); /* -------- Stereoscopic warping --------------*/ #if RUN_WARP pixs = pixRead("german.png"); pixGetDimensions(pixs, &w, &h, NULL); l_jpegSetNoChromaSampling(1); for (i = 0; i < 50; i++) { /* need to test > 2 widths ! */ j = 7 * i; box = boxCreate(0, 0, w - j, h - j); pixt = pixClipRectangle(pixs, box, NULL); pixd = pixWarpStereoscopic(pixt, 15, 22, 8, 30, -20, 1); snprintf(buf, sizeof(buf), "/tmp/junkpixw.%02d.jpg", i); pixWrite(buf, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixDestroy(&pixt); boxDestroy(&box); } pixDestroy(&pixs); pixDisplayMultiple("/tmp/junkpixw*.jpg"); #endif /* -------- Quadratic Vertical Shear --------------*/ #if RUN_QUAD_VERT_SHEAR pixs = pixCreate(501, 501, 32); pixGetDimensions(pixs, &w, &h, NULL); pixSetAll(pixs); pixRenderLineArb(pixs, 0, 30, 500, 30, 5, 0, 0, 255); pixRenderLineArb(pixs, 0, 110, 500, 110, 5, 0, 255, 0); pixRenderLineArb(pixs, 0, 190, 500, 190, 5, 0, 255, 255); pixRenderLineArb(pixs, 0, 270, 500, 270, 5, 255, 0, 0); pixRenderLineArb(pixs, 0, 360, 500, 360, 5, 255, 0, 255); pixRenderLineArb(pixs, 0, 450, 500, 450, 5, 255, 255, 0); bmf = bmfCreate("./fonts", 6); for (i = 0; i < 50; i++) { j = 3 * i; dir = ((i / 2) & 1) ? L_WARP_TO_RIGHT : L_WARP_TO_LEFT; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; Box *box = boxCreate(0, 0, w - j, h - j); pixt = pixClipRectangle(pixs, box, NULL); pixt2 = pixQuadraticVShear(pixt, dir, 60, -20, op, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%s, %s", dirstr[dir], opstr[op]); pixd = pixAddSingleTextblock(pixt2, bmf, buf, 0xff000000, L_ADD_BELOW, 0); snprintf(buf, sizeof(buf), "/tmp/junkpixvs.%02d.png", i); pixWrite(buf, pixd, IFF_PNG); pixDestroy(&pixd); pixDestroy(&pixt); pixDestroy(&pixt2); boxDestroy(&box); } pixDestroy(&pixs); bmfDestroy(&bmf); pixDisplayMultiple("/tmp/junkpixvs*.png"); #endif /* -------- Linear Horizontal stretching --------------*/ #if RUN_LIN_HORIZ_STRETCH pixs = pixRead("german.png"); bmf = bmfCreate("./fonts", 6); for (k = 0; k < 2; k++) { for (i = 0; i < 25; i++) { index = 25 * k + i; stretch = 10 + 4 * i; if (k == 0) stretch = -stretch; dir = (k == 1) ? L_WARP_TO_RIGHT : L_WARP_TO_LEFT; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; pixt = pixStretchHorizontal(pixs, dir, L_LINEAR_WARP, stretch, op, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%s, %s", dirstr[dir], opstr[op]); pixd = pixAddSingleTextblock(pixt, bmf, buf, 0xff000000, L_ADD_BELOW, 0); snprintf(buf, sizeof(buf), "/tmp/junkpixlhs.%02d.jpg", index); pixWrite(buf, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixDestroy(&pixt); } } pixDestroy(&pixs); bmfDestroy(&bmf); pixDisplayMultiple("/tmp/junkpixlhs*.jpg"); #endif /* -------- Quadratic Horizontal stretching --------------*/ #if RUN_QUAD_HORIZ_STRETCH pixs = pixRead("german.png"); bmf = bmfCreate("./fonts", 6); for (k = 0; k < 2; k++) { for (i = 0; i < 25; i++) { index = 25 * k + i; stretch = 10 + 4 * i; if (k == 0) stretch = -stretch; dir = (k == 1) ? L_WARP_TO_RIGHT : L_WARP_TO_LEFT; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; pixt = pixStretchHorizontal(pixs, dir, L_QUADRATIC_WARP, stretch, op, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%s, %s", dirstr[dir], opstr[op]); pixd = pixAddSingleTextblock(pixt, bmf, buf, 0xff000000, L_ADD_BELOW, 0); snprintf(buf, sizeof(buf), "/tmp/junkpixqhs.%02d.jpg", index); pixWrite(buf, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixDestroy(&pixt); } } pixDestroy(&pixs); bmfDestroy(&bmf); pixDisplayMultiple("/tmp/junkpixqhs*.jpg"); #endif /* -------- Horizontal Shear --------------*/ #if RUN_HORIZ_SHEAR pixs = pixRead("german.png"); pixGetDimensions(pixs, &w, &h, NULL); bmf = bmfCreate("./fonts", 6); for (i = 0; i < 25; i++) { del = 0.2 / 12.; angle = -0.2 + (i - (i & 1)) * del; angledeg = 180. * angle / 3.14159265; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; if (op == L_SAMPLED) pixt = pixHShear(NULL, pixs, h / 2, angle, L_BRING_IN_WHITE); else pixt = pixHShearLI(pixs, h / 2, angle, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%6.2f degree, %s", angledeg, opstr[op]); pixd = pixAddSingleTextblock(pixt, bmf, buf, 0xff000000, L_ADD_BELOW, 0); snprintf(buf, sizeof(buf), "/tmp/junkpixsh.%02d.jpg", i); pixWrite(buf, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixDestroy(&pixt); } pixDestroy(&pixs); bmfDestroy(&bmf); pixDisplayMultiple("/tmp/junkpixsh*.jpg"); #endif /* -------- Vertical Shear --------------*/ #if RUN_VERT_SHEAR pixs = pixRead("german.png"); pixGetDimensions(pixs, &w, &h, NULL); bmf = bmfCreate("./fonts", 6); for (i = 0; i < 25; i++) { del = 0.2 / 12.; angle = -0.2 + (i - (i & 1)) * del; angledeg = 180. * angle / 3.14159265; op = (i & 1) ? L_INTERPOLATED : L_SAMPLED; if (op == L_SAMPLED) pixt = pixVShear(NULL, pixs, w / 2, angle, L_BRING_IN_WHITE); else pixt = pixVShearLI(pixs, w / 2, angle, L_BRING_IN_WHITE); snprintf(buf, sizeof(buf), "%6.2f degree, %s", angledeg, opstr[op]); pixd = pixAddSingleTextblock(pixt, bmf, buf, 0xff000000, L_ADD_BELOW, 0); snprintf(buf, sizeof(buf), "/tmp/junkpixsv.%02d.jpg", i); pixWrite(buf, pixd, IFF_JFIF_JPEG); pixDestroy(&pixd); pixDestroy(&pixt); } pixDestroy(&pixs); bmfDestroy(&bmf); pixDisplayMultiple("/tmp/junkpixsv*.jpg"); #endif return 0; }