示例#1
0
main(int    argc,
     char **argv)
{
    char        *filein, *fileout;
    l_int32      d;
    l_float32    scalex, scaley;
    PIX         *pixs, *pixd;
    static char  mainName[] = "scaletest1";

    if (argc != 5)
        return ERROR_INT(" Syntax:  scaletest1 filein scalex scaley fileout",
                         mainName, 1);

    filein = argv[1];
    scalex = atof(argv[2]);
    scaley = atof(argv[3]);
    fileout = argv[4];

    if ((pixs = pixRead(filein)) == NULL)
        return ERROR_INT("pixs not made", mainName, 1);

    /* choose type of scaling operation */
#if 1
    pixd = pixScale(pixs, scalex, scaley);
#elif 0
    pixd = pixScaleLI(pixs, scalex, scaley);
#elif 0
    pixd = pixScaleSmooth(pixs, scalex, scaley);
#elif 0
    pixd = pixScaleAreaMap(pixs, scalex, scaley);
#elif 0
    pixd = pixScaleBySampling(pixs, scalex, scaley);
#else
    pixd = pixScaleToGray(pixs, scalex);
#endif

    d = pixGetDepth(pixd);

#if 1
    if (d <= 8)
        pixWrite(fileout, pixd, IFF_PNG);
    else
        pixWrite(fileout, pixd, IFF_JFIF_JPEG);
#else
    pixWrite(fileout, pixd, IFF_PNG);
#endif

    pixDestroy(&pixs);
    pixDestroy(&pixd);
    return 0;
}
示例#2
0
/*
 *  pixWriteSegmentedPageToPS()
 *
 *      Input:  pixs (all depths; colormap ok)
 *              pixm (<optional> 1 bpp segmentation mask over image region)
 *              textscale (scale of text output relative to pixs)
 *              imagescale (scale of image output relative to pixs)
 *              threshold (threshold for binarization; typ. 190)
 *              pageno (page number in set; use 1 for new output file)
 *              fileout (output ps file)
 *      Return: 0 if OK, 1 on error
 *
 *  Notes:
 *      (1) This generates the PS string for a mixed text/image page,
 *          and adds it to an existing file if @pageno > 1.
 *          The PS output is determined by fitting the result to
 *          a letter-size (8.5 x 11 inch) page.
 *      (2) The two images (pixs and pixm) are at the same resolution
 *          (typically 300 ppi).  They are used to generate two compressed
 *          images, pixb and pixc, that are put directly into the output
 *          PS file.
 *      (3) pixb is the text component.  In the PostScript world, we think of
 *          it as a mask through which we paint black.  It is produced by
 *          scaling pixs by @textscale, and thresholding to 1 bpp.
 *      (4) pixc is the image component, which is that part of pixs under
 *          the mask pixm.  It is scaled from pixs by @imagescale.
 *      (5) Typical values are textscale = 2.0 and imagescale = 0.5.
 *      (6) If pixm == NULL, the page has only text.  If it is all black,
 *          the page is all image and has no text.
 *      (7) This can be used to write a multi-page PS file, by using
 *          sequential page numbers with the same output file.  It can
 *          also be used to write separate PS files for each page,
 *          by using different output files with @pageno = 0 or 1.
 */
l_int32
pixWriteSegmentedPageToPS(PIX         *pixs,
                          PIX         *pixm,
                          l_float32    textscale,
                          l_float32    imagescale,
                          l_int32      threshold,
                          l_int32      pageno,
                          const char  *fileout)
{
l_int32    alltext, notext, d, ret;
l_uint32   val;
l_float32  scaleratio;
PIX       *pixmi, *pixmis, *pixt, *pixg, *pixsc, *pixb, *pixc;

    PROCNAME("pixWriteSegmentedPageToPS");

    if (!pixs)
        return ERROR_INT("pixs not defined", procName, 1);
    if (!fileout)
        return ERROR_INT("fileout not defined", procName, 1);
    if (imagescale <= 0.0 || textscale <= 0.0)
        return ERROR_INT("relative scales must be > 0.0", procName, 1);

        /* Analyze the page.  Determine the ratio by which the
         * binary text mask is scaled relative to the image part.
         * If there is no image region (alltext == TRUE), the
         * text mask will be rendered directly to fit the page,
         * and scaleratio = 1.0.  */
    alltext = TRUE;
    notext = FALSE;
    scaleratio = 1.0;
    if (pixm) {
        pixZero(pixm, &alltext);  /* pixm empty: all text */
        if (alltext)
            pixm = NULL;  /* treat it as not existing here */
        else {
            pixmi = pixInvert(NULL, pixm);
            pixZero(pixmi, &notext);  /* pixm full; no text */
            pixDestroy(&pixmi);
            scaleratio = textscale / imagescale;
        }
    }

    if (pixGetDepth(pixs) == 1) {  /* render tiff g4 */
        pixb = pixClone(pixs);
        pixc = NULL;
    }
    else {
        pixt = pixConvertTo8Or32(pixs, 0, 0);  /* this can be a clone of pixs */

            /* Get the binary text mask.  Note that pixg cannot be a
             * clone of pixs, because it may be altered by pixSetMasked(). */
        pixb = NULL;
        if (notext == FALSE) {
            d = pixGetDepth(pixt);
            if (d == 8)
                pixg = pixCopy(NULL, pixt);
            else  /* d == 32 */
                pixg = pixConvertRGBToLuminance(pixt);
            if (pixm)  /* clear out the image parts */
                pixSetMasked(pixg, pixm, 255);
            if (textscale == 1.0)
                pixsc = pixClone(pixg);
            else if (textscale >= 0.7)
                pixsc = pixScaleGrayLI(pixg, textscale, textscale);
            else
                pixsc = pixScaleAreaMap(pixg, textscale, textscale);
            pixb = pixThresholdToBinary(pixsc, threshold);
            pixDestroy(&pixg);
            pixDestroy(&pixsc);
        }

            /* Get the scaled image region */
        pixc = NULL;
        if (pixm) {
            if (imagescale == 1.0)
                pixsc = pixClone(pixt);  /* can possibly be a clone of pixs */
            else
                pixsc = pixScale(pixt, imagescale, imagescale);

                /* If pixm is not full, clear the pixels in pixsc
                 * corresponding to bg in pixm, where there can be text
                 * that is written through the mask pixb.  Note that
                 * we could skip this and use pixsc directly in
                 * pixWriteMixedToPS(); however, clearing these
                 * non-image regions to a white background will reduce
                 * the size of pixc (relative to pixsc), and hence
                 * reduce the size of the PS file that is generated.
                 * Use a copy so that we don't accidentally alter pixs.  */
            if (notext == FALSE) {
                pixmis = pixScale(pixm, imagescale, imagescale);
                pixmi = pixInvert(NULL, pixmis);
                val = (d == 8) ? 0xff : 0xffffff00;
                pixc = pixCopy(NULL, pixsc);
                pixSetMasked(pixc, pixmi, val);  /* clear non-image part */
                pixDestroy(&pixmis);
                pixDestroy(&pixmi);
            }
            else
                pixc = pixClone(pixsc);
            pixDestroy(&pixsc);
        }
        pixDestroy(&pixt);
    }

    ret = pixWriteMixedToPS(pixb, pixc, scaleratio, pageno, fileout);
    pixDestroy(&pixb);
    pixDestroy(&pixc);
    return ret;
}
示例#3
0
main(int    argc,
     char **argv)
{
l_int32      i;
l_float32    pi, scale, angle;
PIX         *pixc, *pixm, *pix1, *pix2, *pix3;
PIXA        *pixa;
PTA         *pta1, *pta2, *pta3, *pta4;
static char  mainName[] = "smallpix_reg";

        /* Make a small test image, the hard way! */
    pi = 3.1415926535;
    pixc = pixCreate(9, 9, 32);
    pixm = pixCreate(9, 9, 1);
    pta1 = generatePtaLineFromPt(4, 4, 3.1, 0.0);
    pta2 = generatePtaLineFromPt(4, 4, 3.1, 0.5 * pi);
    pta3 = generatePtaLineFromPt(4, 4, 3.1, pi);
    pta4 = generatePtaLineFromPt(4, 4, 3.1, 1.5 * pi);
    ptaJoin(pta1, pta2, 0, 0);
    ptaJoin(pta1, pta3, 0, 0);
    ptaJoin(pta1, pta4, 0, 0);
    pixRenderPta(pixm, pta1, L_SET_PIXELS);
    pixPaintThroughMask(pixc, pixm, 0, 0, 0x00ff0000);
    ptaDestroy(&pta1);
    ptaDestroy(&pta2);
    ptaDestroy(&pta3);
    ptaDestroy(&pta4);
    pixDestroy(&pixm);

        /* Results differ for scaleSmoothLow() w/ and w/out + 0.5.
         * Neither is properly symmetric (with symm pattern on odd-sized
         * pix, because the smoothing is destroying the symmetry. */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 2);
    for (i = 0; i < 11; i++) {
        scale = 0.30 + 0.035 * (l_float32)i;
        pix2 = pixScaleSmooth(pix1, scale, scale);
        pix3 = pixExpandReplicate(pix2, 6);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 100, NULL);

        /* Results same for pixScaleAreaMap w/ and w/out + 0.5 */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 2);
    for (i = 0; i < 11; i++) {
        scale = 0.30 + 0.035 * (l_float32)i;
        pix2 = pixScaleAreaMap(pix1, scale, scale);
        pix3 = pixExpandReplicate(pix2, 6);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 200, NULL);

        /* Results better for pixScaleBySampling with + 0.5, for small,
         * odd-dimension pix.  */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 2);
    for (i = 0; i < 11; i++) {
        scale = 0.30 + 0.035 * (l_float32)i;
        pix2 = pixScaleBySampling(pix1, scale, scale);
        pix3 = pixExpandReplicate(pix2, 6);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 300, NULL);

        /* Results same for pixRotateAM w/ and w/out + 0.5 */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 1);
    for (i = 0; i < 11; i++) {
        angle = 0.10 + 0.05 * (l_float32)i;
        pix2 = pixRotateAM(pix1, angle, L_BRING_IN_BLACK);
        pix3 = pixExpandReplicate(pix2, 8);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 400, NULL);

        /* If the size is odd, we express the center exactly, and the
         * results are better for pixRotateBySampling() w/out 0.5
         * However, if the size is even, the center value is not
         * exact, and if we choose it 0.5 smaller than the actual
         * center, we get symmetrical results with +0.5. 
         * So we choose not to include + 0.5. */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 1);
    for (i = 0; i < 11; i++) {
        angle = 0.10 + 0.05 * (l_float32)i;
        pix2 = pixRotateBySampling(pix1, 4, 4, angle, L_BRING_IN_BLACK);
        pix3 = pixExpandReplicate(pix2, 8);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 500, NULL);

        /* Results same for pixRotateAMCorner w/ and w/out + 0.5 */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 1);
    for (i = 0; i < 11; i++) {
        angle = 0.10 + 0.05 * (l_float32)i;
        pix2 = pixRotateAMCorner(pix1, angle, L_BRING_IN_BLACK);
        pix3 = pixExpandReplicate(pix2, 8);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 600, NULL);

        /* Results better for pixRotateAMColorFast without + 0.5 */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 1);
    for (i = 0; i < 11; i++) {
        angle = 0.10 + 0.05 * (l_float32)i;
        pix2 = pixRotateAMColorFast(pix1, angle, 0);
        pix3 = pixExpandReplicate(pix2, 8);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 700, NULL);

        /* Results slightly better for pixScaleColorLI() w/out + 0.5 */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 1);
    for (i = 0; i < 11; i++) {
        scale = 1.0 + 0.2 * (l_float32)i;
        pix2 = pixScaleColorLI(pix1, scale, scale);
        pix3 = pixExpandReplicate(pix2, 4);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 800, NULL);

        /* Results slightly better for pixScaleColorLI() w/out + 0.5 */
    pixa = pixaCreate(11);
    pix1 = pixExpandReplicate(pixc, 1);
    for (i = 0; i < 11; i++) {
        scale = 1.0 + 0.2 * (l_float32)i;
        pix2 = pixScaleLI(pix1, scale, scale);
        pix3 = pixExpandReplicate(pix2, 4);
        pixSaveTiled(pix3, pixa, 1, (i == 0), 20, 32);
        pixDestroy(&pix2);
        pixDestroy(&pix3);
    }
    pixDestroy(&pix1);
    DisplayPix(&pixa, 100, 940, NULL);

    pixDestroy(&pixc);
    return 0;
}