void Bitmap::copyRectFromBitmap(const Bitmap& src, unsigned srcCol, unsigned srcRow, unsigned destCol, unsigned destRow, unsigned width, unsigned height) { if (srcCol == 0 && srcRow == 0 && width == 0 && height == 0){ width = src.width(); height = src.height(); } if (width == 0 || height == 0) throw std::runtime_error("Can't copy zero height/width rectangle"); if (srcCol + width >= src.width() || srcRow + height >= src.height()) throw std::runtime_error("Rectangle doesn't fit within source bitmap"); if (destCol + width >= _width || destRow + height >= _height) throw std::runtime_error("Rectangle doesn't fit within destination bitmap"); if (_pixels == src._pixels && RectsOverlap(srcCol, srcRow, destCol, destRow, width, height)) throw std::runtime_error("Source and destination are the same bitmap, and rects overlap. Not allowed!"); FormatConverterFunc converter = NULL; if(_format != src._format) converter = ConverterFuncForFormats(_format, src._format); for (unsigned row = 0; row < height; ++row) { for (unsigned col = 0; col < width; ++col) { unsigned char *srcPixel = src._pixels + GetPixelOffset(srcCol + col, srcRow + row, src._width, src._height, src._format); unsigned char *destPixel = _pixels + GetPixelOffset(destCol + col, destRow + row, _width, _height, _format); if (converter) { converter(srcPixel, destPixel); } else { memcpy(destPixel, srcPixel, _format); } } } }
/************************************************************************* * * \函数名称: * GetPixel() * * \输入参数: * int x - 象素在X轴的坐标 * int y - 象素在Y轴的坐标 * * \返回值: * RGBQUAD - 返回DIB在该点真实的颜色 * * \说明: * 该函数得到DIB图象在该点真是的颜色。 * ************************************************************************ */ RGBQUAD CDib::GetPixel(int x, int y) { // 颜色结构 RGBQUAD cColor; // 根据每象素比特数得到此点的象素值 switch (m_lpBMIH->biBitCount) { case 1 : if (1<<(7-x%8) & *(LPBYTE)(m_lpImage+GetPixelOffset(x, y))) { cColor.rgbBlue = 255; cColor.rgbGreen = 255; cColor.rgbRed = 255; cColor.rgbReserved =0; } else { cColor.rgbBlue = 0; cColor.rgbGreen = 0; cColor.rgbRed = 0; cColor.rgbReserved =0; } break; case 4 : { int nIndex = (*(LPBYTE)(m_lpImage+GetPixelOffset(x, y)) & (x%2 ? 0x0f : 0xf0)) >> (x%2 ? 0 : 4); LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex; cColor.rgbBlue = pDibQuad->rgbBlue; cColor.rgbGreen = pDibQuad->rgbGreen; cColor.rgbRed = pDibQuad->rgbRed; cColor.rgbReserved =0; } break; case 8 : { int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y)); LPRGBQUAD pDibQuad = (LPRGBQUAD) (m_lpvColorTable) + nIndex; cColor.rgbBlue = pDibQuad->rgbBlue; cColor.rgbGreen = pDibQuad->rgbGreen; cColor.rgbRed = pDibQuad->rgbRed; cColor.rgbReserved =0; } break; default: int nIndex = *(BYTE*)(m_lpImage+GetPixelOffset(x, y)); cColor.rgbRed = m_lpImage[nIndex]; cColor.rgbGreen = m_lpImage[nIndex + 1]; cColor.rgbBlue = m_lpImage[nIndex + 2]; cColor.rgbReserved =0; break; } // 返回颜色结构 return cColor; }
void Bitmap::flipVertically() { unsigned long rowSize = _format*_width; unsigned char* rowBuffer = new unsigned char[rowSize]; unsigned halfRows = _height / 2; for(unsigned rowIdx = 0; rowIdx < halfRows; ++rowIdx) { unsigned char* row = _pixels + GetPixelOffset(0, rowIdx, _width, _height, _format); unsigned char* oppositeRow = _pixels + GetPixelOffset(0, _height - rowIdx - 1, _width, _height, _format); memcpy(rowBuffer, row, rowSize); memcpy(row, oppositeRow, rowSize); memcpy(oppositeRow, rowBuffer, rowSize); } delete rowBuffer; }
void Bitmap::rotate90CounterClockwise() { unsigned char* newPixels = (unsigned char*) malloc(_format*_width*_height); for(unsigned row = 0; row < _height; ++row) { for(unsigned col = 0; col < _width; ++col) { unsigned srcOffset = GetPixelOffset(col, row, _width, _height, _format); unsigned destOffset = GetPixelOffset(row, _width - col - 1, _height, _width, _format); memcpy(newPixels + destOffset, _pixels + srcOffset, _format); //copy one pixel } } free(_pixels); _pixels = newPixels; unsigned swapTmp = _height; _height = _width; _width = swapTmp; }
cv::Mat FLImageToMat(const Fl_Image* img) { cv::Mat mat = cv::Mat::zeros(img->h(), img->w(), CV_8UC3); for (int x = 0; x < img->w(); ++x) { for (int y = 0; y < img->h(); ++y) { cv::Vec3b& cvp = mat.at<cv::Vec3b>(y, x); long index = GetPixelOffset(img, x, y); switch ( img->count() ) { case 1: { const char *buf = img->data()[0]; switch ( img->d() ) { case 1: { cvp[0] = cvp[1] = cvp[2] = *(buf+index); break; } case 3: cvp[2] = *(buf+index+0); cvp[1] = *(buf+index+1); cvp[0] = *(buf+index+2); break; } break; } } } } return mat; }
Fl_Image* MatToFLImage(const cv::Mat& mat) { const int depth = 3; std::vector<unsigned char> newData(mat.cols * mat.rows * depth); unsigned char* buf = newData.data(); for (int x = 0; x < mat.cols; ++x) { for (int y = 0; y < mat.rows; ++y) { const cv::Vec3b& cvp = mat.at<cv::Vec3b>(y, x); long index = GetPixelOffset(x, y, mat.cols, depth); *(buf+index+0) = cvp[2]; *(buf+index+1) = cvp[1]; *(buf+index+2) = cvp[0]; } } std::unique_ptr<Fl_RGB_Image> newImage(new Fl_RGB_Image(newData.data(), mat.cols, mat.rows, depth, 0)); Fl_Image* rez = newImage->copy(); return rez; }
unsigned char* Bitmap::getPixel(unsigned int column, unsigned int row) const { if(column >= _width || row >= _height) throw std::runtime_error("Pixel coordinate out of bounds"); return _pixels + GetPixelOffset(column, row, _width, _height, _format); }