📄 imgs.cpp
字号:
pixel |= *dest & ((1 << (8 - bit - bit)) - 1); *dest++ = pixel; //new pixel } } else { pixperbyte = 8; dest += x / 8; //offset on line bit = (inT8) (x % 8); //offset in byte width += bit; pixel = *dest >> (8 - bit); while (width >= 8) { //until all done for (; bit < 8; bit++) { pixel <<= 1; //make space for new one pixel |= *src & 1; src += bytesperpix; } *dest++ = pixel; //new pixel width -= 8; bit = 0; } width -= bit; if (width > 0) { //until all done while (width > 0) { pixel <<= 1; //make space for new one pixel |= *src & 1; src += bytesperpix; bit++; width--; } pixel <<= (8 - bit); //shift rest //keep trainling bits pixel |= *dest & ((1 << (8 - bit)) - 1); *dest++ = pixel; //new pixel } }}/********************************************************************** * put_column * * Put the supplied column buffer into the image. * The image is converted from 8bpp by simple assignment. **********************************************************************/void IMAGE::put_column( //put image column inT32 x, //coord to start at inT32 y, //line to get inT32 height, //no of pixels to get IMAGELINE *linebuf, //line to copy to inT32 margins //margins in buffer ) { uinT8 *src; //source pointer uinT8 *dest; //destination pointer inT8 bit; //bit index uinT8 pixel; //collected bits inT8 bytesperpix; //in source this->check_legal_access (x, y, 1); this->check_legal_access (x, y + height - 1, 1); if (height > ysize - y) height = ysize - y; //clip to image if (height <= 0) return; //nothing to do //source line src = linebuf->pixels + margins; //start of line dest = image + xdim * (ymax - 1 - y); if (linebuf->bpp == 24) { src++; bytesperpix = 3; } else bytesperpix = 1; if (bpp == 24 && linebuf->bpp == 24) { dest += x * bytesperpix; src--; for (; height > 0; --height) { *dest = *src++; *(dest + 1) = *src++; *(dest + 2) = *src++; dest -= xdim; } } else if (bpp == 24) { src--; dest += x * bytesperpix; for (; height > 0; --height) { pixel = *src++; *dest = pixel; *(dest + 1) = pixel; *(dest + 2) = pixel; dest -= xdim; } } else if (bpp > 4) { dest += x; //offset for (; height > 0; --height) { *dest = *src; src += bytesperpix; dest -= xdim; } } else if (bpp == 4) { dest += x / 2; //offset on line if (x & 1) { for (; height > 0; --height) { *dest &= 0xf0; //clean odd byte *dest |= *src & 0x0f; //and copy it src += bytesperpix; dest -= xdim; } } else { for (; height > 0; --height) { *dest &= 0x0f; //clean odd byte *dest |= *src << 4; src += bytesperpix; dest -= xdim; } } } else if (bpp == 2) { dest += x / 4; //offset on line bit = (inT8) (x % 4); //offset in byte bit = 6 - bit - bit; //bit shift pixel = ~(3 << bit); //mask for (; height > 0; --height) { //change 2 bits *dest = (*dest & pixel) | ((*src & 3) << bit); src += bytesperpix; dest -= xdim; } } else { dest += x / 8; //offset on line bit = (inT8) (x % 8); //offset in byte bit = 7 - bit; pixel = ~(1 << bit); for (; height > 0; --height) { //change 1 bit *dest = (*dest & pixel) | ((*src & 1) << bit); src += bytesperpix; dest -= xdim; } }}/********************************************************************** * check_legal_access * * Check that x,y are within the bounds of the image. * Call bufread if necessary to get the image into memory. **********************************************************************/void IMAGE::check_legal_access( //check coords are legal inT32 x, //coords to check inT32 y, inT32 xext //xextent ) { if (x < 0 || x >= xsize || y < 0 || y >= ysize || x + xext > xsize) BADIMAGECOORDS.error ("IMAGE::check_legal_access", ABORT, "(%d+%d,%d)", x, xext, y); if (y >= ymax) BADIMAGESEEK.error ("IMAGE::check_legal_access", ABORT, "(%d,%d)", x, y); if (y < ymin) bufread(y); //read some more}#ifdef HAVE_LIBLEPT// ONLY available if you have Leptonica installed./********************************************************************** * ToPix * * Make a Pix from this image. **********************************************************************/Pix* IMAGE::ToPix() { int width = this->get_xsize(); int height = this->get_ysize(); int bpp = this->get_bpp(); Pix* pix = pixCreate(width, height, bpp == 24 ? 32 : bpp); uint32* data = pixGetData(pix); IMAGELINE line; if (bpp == 24) { line.init(width * 3); line.set_bpp(24); } else { line.init(width); } switch (bpp) { case 1: for (int y = height - 1 ; y >= 0; --y) { this->get_line(0, y, width, &line, 0); for (int x = 0; x < width; ++x) { if (line.pixels[x]) CLEAR_DATA_BIT(data, x); else SET_DATA_BIT(data, x); } data += pixGetWpl(pix); } break; case 8: // Greyscale just copies the bytes in the right order. for (int y = height - 1 ; y >= 0; --y) { this->get_line(0, y, width, &line, 0); for (int x = 0; x < width; ++x) SET_DATA_BYTE(data, x, line.pixels[x]); data += pixGetWpl(pix); } break; case 24: // Put the colors in the correct places in the line buffer. for (int y = height - 1 ; y >= 0; --y) { this->get_line(0, y, width, &line, 0); for (int x = 0; x < width; ++x, ++data) { SET_DATA_BYTE(data, COLOR_RED, line[x][RED_PIX]); SET_DATA_BYTE(data, COLOR_GREEN, line[x][GREEN_PIX]); SET_DATA_BYTE(data, COLOR_BLUE, line[x][BLUE_PIX]); } } break; default: tprintf("Cannot convert image to Pix with bpp = %d\n", bpp); } return pix;}/********************************************************************** * FromPix * * Copy from the given Pix into this image. **********************************************************************/void IMAGE::FromPix(const Pix* src_pix) { // Leptonica doesn't const its inputs, but we don't change the input. Pix* pix = const_cast<Pix*>(src_pix); Pix* destroy_this_pix = NULL; int depth = pixGetDepth(pix); if (depth > 1 && depth < 8) { // Convert funny depths to 8 bit. destroy_this_pix = pixConvertTo8(pix, false); pix = destroy_this_pix; depth = pixGetDepth(pix); } int width = pixGetWidth(pix); int height = pixGetHeight(pix); const uint32* data = pixGetData(pix); this->create(width, height, depth == 32 ? 24 : depth); // For each line in the image, fill the IMAGELINE class and put it into the // destination image. Note that Tesseract stores images with the // bottom at y=0 and 0 is always black in grey and binary. IMAGELINE line; if (depth == 32) { line.init(width * 3); line.set_bpp(24); } else { line.init(width); } switch (depth) { case 1: // Binary images just flip the data bit. for (int y = height - 1 ; y >= 0; --y) { for (int x = 0; x < width; ++x) line.pixels[x] = GET_DATA_BIT(data, x) ^ 1; this->put_line(0, y, width, &line, 0); data += pixGetWpl(pix); } break; case 8: // Greyscale just copies the bytes in the right order. for (int y = height - 1 ; y >= 0; --y) { for (int x = 0; x < width; ++x) line.pixels[x] = GET_DATA_BYTE(data, x); this->put_line(0, y, width, &line, 0); data += pixGetWpl(pix); } break; case 32: // Put the colors in the correct places in the line buffer. for (int y = height - 1 ; y >= 0; --y) { for (int x = 0; x < width; ++x, ++data) { line[x][RED_PIX] = GET_DATA_BYTE(data, COLOR_RED); line[x][GREEN_PIX] = GET_DATA_BYTE(data, COLOR_GREEN); line[x][BLUE_PIX] = GET_DATA_BYTE(data, COLOR_BLUE); } this->put_line(0, y, width, &line, 0); } break; default: tprintf("Cannot convert Pix to image with bpp = %d\n", depth); } if (destroy_this_pix != NULL) pixDestroy(&destroy_this_pix);}#endif // HAVE_LIBLEPT/************************************************************************* * convolver() * * Calls the specified function for each pixel in the image, passing in an m x n * window of the image, centred on the pixel. The convolution function returns * a new value for the pixel, based on the window. * * At the edges of the image, the window is padded to white pixels. *************************************************************************/voidIMAGE::convolver ( //Map fn over windowinT32 win_width, //Window widthinT32 win_height, //Window heightvoid (*convolve) ( //Conv FunctionuinT8 ** pixels, //Of windowuinT8 bytespp, //1 or 3 for colourinT32 win_wd, //Window widthinT32 win_ht, //Window heightuinT8 ret_white_value, //White value to RETURNuinT8 * result) //Ptr to result pix) { IMAGELINE new_row; //Replacement pixels IMAGELINE *old_rows; //Rows being processed inT32 oldest_imline; //Next imline to replace uinT8 **window; //ptrs to pixel rows uinT8 **winmax; //ptrs to pixel rows uinT8 **win; //ptrs to pixel rows inT32 current_row; //Row being calculated inT32 current_col; //Col being calculated inT32 row = 0; //Next row to get inT32 i, j; uinT8 *pix; uinT8 *max; inT32 xmargin = win_width / 2; inT32 ymargin = win_height / 2; uinT8 white = get_white_level (); const uinT8 max_white = 255; float white_scale = (float) 255 / get_white_level (); if (((win_width % 2) == 0) || ((win_height % 2) == 0) || (win_height < 3) || (win_width < 3) || (win_height > ysize / 2) || (win_width > xsize / 2)) BADWINDOW.error ("IMAGE::convolver", ABORT, "(%d x %d)", win_width, win_height); new_row.init (xsize * bytespp); new_row.set_bpp (bpp); old_rows = new IMAGELINE[win_height]; for (i = 0; i < win_height; i++) { old_rows[i].init ((xsize + 2 * xmargin) * bytespp); old_rows[i].set_bpp (bpp); } window = (uinT8 **) alloc_mem (win_height * sizeof (uinT8 *)); winmax = window + win_height; /* Make bottom border */ for (oldest_imline = 0; oldest_imline < ymargin; oldest_imline++) { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) *pix++ = max_white; } /* Initialise remaining rows but one*/ for (; oldest_imline < win_height - 1; oldest_imline++) { get_line (0, row++, xsize, &old_rows[oldest_imline], xmargin); if (max_white != white) { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) { *pix = (uinT8) (*pix * white_scale); ++pix; } } } /* Image Processing */ for (current_row = 0; current_row < ysize;) { /* Get next row and re-initialise window array */ if (row < ysize) { get_line (0, row++, xsize, &old_rows[oldest_imline], xmargin); if (max_white != white) { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) { *pix = (uinT8) (*pix * white_scale); ++pix; } } } else { pix = old_rows[oldest_imline].pixels; max = pix + (xsize + 2 * xmargin) * bytespp; while (pix < max) *pix++ = max_white; } oldest_imline++; if (oldest_imline >= win_height) oldest_imline = 0; /* Process line */ pix = new_row.pixels; for (current_col = 0; current_col < xsize;) { /* Set up window ptrs */ if (current_col == 0) { j = oldest_imline; for (i = 0; i < win_height; i++) { window[i] = old_rows[j++].pixels; if (j >= win_height) j = 0; } } else { for (win = window; win < winmax; (*win++) += bytespp); //Move along rows } convolve(window, bytespp, win_width, win_height, white, pix); pix += bytespp; current_col++; } put_line (0, current_row, xsize, &new_row, 0); new_row.init (); new_row.set_bpp (bpp); current_row++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -