📄 rgbimutil.cpp
字号:
Img.dim(nNewWidth, nNewHeight); tRGB *pOut = Img.buf; pIn = Out1.buf; for (ix = 0; ix < nNewWidth; ix++) { for (iy = 0; iy < nNewHeight; iy++) pOut[ix + iy * nNewWidth] = InterpolateRgbPixel(pIn, iy, scaleY, height); pIn += height; } }}//-----------------------------------------------------------------------------void ConvertGrayImageToRgb (RgbImage &OutImg, // out const Image &Img) // in{int width = Img.width;int height = Img.height;OutImg.dim(width, height);for (int iy = 0; iy < height; iy++) for (int ix = 0; ix < width; ix++) { tRGB Pix; Pix.Red = Pix.Green = Pix.Blue = Img(ix + ((height - 1 - iy) * width)); OutImg(ix, iy) = Pix; }}//-----------------------------------------------------------------------------void ConvertRgbImageToGray (Image &OutImg, // out const RgbImage &Img) // in{int width = Img.width;int height = Img.height;OutImg.dim(width, height);for (int iy = 0; iy < height; iy++) for (int ix = 0; ix < width; ix++) { // CIE conversion to gray, add 500 to take care of rounding tRGB Rgb = Img(ix + ((height - 1 - iy) * width)); OutImg(ix, iy) = (byte)RgbToGray(Rgb); }}//-----------------------------------------------------------------------------// Draw the given rectangle into Img// If co-ords or sizes are out-of-range we force them in rangevoid DrawRectInBmp (RgbImage &Img, // io int ix, int iy, int nxSize, int nySize, unsigned Color) // in{int i;byte Blue = byte(Color & 0xff);byte Green = byte((Color >> 8) & 0xff);byte Red = byte((Color >> 16) & 0xff);// force parameters in rangeint width = Img.width;int height = Img.height;if (ix < 0) ix = 0;if (nxSize < 1) nxSize = 1;if (ix >= width) ix = width-1;if (ix + nxSize >= width) nxSize = width - ix;// convert PGM coords to BMP coordsiy = height - iy - nySize;if (iy < 0) iy = 0;if (nySize < 1) nySize = 1;if (iy >= height) iy = height-1;if (iy + nySize >= height) nySize = height - iy;for (i = 0; i < nxSize; i++) { tRGB *p = &Img(ix+i, iy); // top p->Red = Red; p->Blue = Blue; p->Green = Green; p = &Img((ix+i) + width * (iy+nySize-1)); // bottom p->Red = Red; p->Blue = Blue; p->Green = Green; }for (i = 0; i < nySize; i++) { tRGB *p = &Img(ix, iy+i); // left p->Red = Red; p->Blue = Blue; p->Green = Green; p = &Img((ix+nxSize-1) + width * (iy+i)); // right p->Red = Red; p->Blue = Blue; p->Green = Green; }}//-----------------------------------------------------------------------------void FillRgbImage (RgbImage &Img, byte Red, byte Green, byte Blue){for (int i = 0; i < Img.width * Img.height; i++) { Img.buf[i].Red = Red; Img.buf[i].Green = Green; Img.buf[i].Blue = Blue; }}//-----------------------------------------------------------------------------static void CheckWindowsReturn (bool fSuccess, char *sFile, int iLine){if (!fSuccess) { LPVOID lpMsgBuf; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL); SysErr("%s %d Windows error: %s", sFile, iLine, lpMsgBuf); LocalFree(lpMsgBuf); }}//-----------------------------------------------------------------------------// Convert an RgbImage to a Windows hdc, and back again.//// This allows you to manipulate an RgbImage using the Windows library functions.// Not an efficient process, but useful.//// fFromImgToHdc=true convert from RgbImage to hdc// false convert from hdc back to RgbImage//// The temporary image we generate for writing has the same color characteristics// as the screen this program is running on. Weird, but that seems to be the only// way under Windows. It means if you are on a monochrome screen, for example,// the RgbImage will be converted to monochrome.//// The mechanism is (in RgbImage to hdcMem direction)// 1. Create a Windows bitmap: CreateCompatibleBitmap()// 2. Copy RgbImage into bitmap: SetDIBits// 3. Select the bitmap into a memory device context: SelectObject// Anything subsequently written into the memory device hdcMem will // also be written into the bitmap//// In the other direction, we copy the bitmap back into the RgbImage//// Look for "The Memory Device Context" in Petzold's book(s) for details.// I used "Programming Windows 95" page 489.static void ConvertRgbToWindowsHdc (RgbImage &Img, HDC &hdcMem, bool fFromImgToHdc){static HDC hdc;static HBITMAP hBmp;static tagBITMAPINFOHEADER bmi = { 40, // biSize 0, // biWidth 0, // biHeight 1, // biPlanes 24, // biBitCount 0, // biCompression 0, // biSizeImage 7085, // biXPelsPerMeter (this value copied from an existing bitmap) 7085, // biYPelsPerMeter (ditto) 0, // biClrUsed 0 // biClrImportant };if (Img.width % 4) //TODO for now, silently don't write into images with width not divisible by 4 return;if (fFromImgToHdc) { hdc = GetDC(NULL); CheckWindowsReturn((hBmp = CreateCompatibleBitmap(hdc, Img.width, Img.height)) != NULL, __FILE__, __LINE__); bmi.biWidth = Img.width; bmi.biHeight = Img.height; CheckWindowsReturn(SetDIBits(hdc, hBmp, 0, Img.height, (CONST VOID *)(Img.buf), LPBITMAPINFO(&bmi), DIB_RGB_COLORS) != 0, __FILE__, __LINE__); CheckWindowsReturn((hdcMem = CreateCompatibleDC(NULL)) != NULL, __FILE__, __LINE__); SelectObject(hdcMem, hBmp); }else { DeleteDC(hdcMem); // needed BEFORE GetDIBits (I think) CheckWindowsReturn(GetDIBits(hdc, hBmp, 0, Img.height, LPVOID(Img.buf), LPBITMAPINFO(&bmi), DIB_RGB_COLORS) != 0, __FILE__, __LINE__); ReleaseDC(NULL, hdc); DeleteObject(hBmp); }}//-----------------------------------------------------------------------------// Print text into an image, at image coords ix and iy// Use iFontSize==0 to get the default size// Current implementation is very slowvoid __cdecl RgbPrintf (RgbImage &Img, // io int ix, int iy, unsigned Color, int iFontSize, const char *pArgs, ...) // in: args like printf{static bool fWarningIssued;if (!fWarningIssued && Img.width % 4) { fWarningIssued = true; Warn("Can't print \"%s\" into image because image width is not divisible by 4", pArgs); EnterDebugger; return; }HDC hdcMem;ConvertRgbToWindowsHdc(Img, hdcMem, true);va_list pArg; // format pArgs... into schar s[SLEN];va_start(pArg, pArgs);vsprintf(s, pArgs, pArg);va_end(pArg);// Removed DASSERT because it's okay to try to write outside extent of image.// For example, when labelling a shape where the shape is not wholly contained in the image.// TestOut() simply doesn't write text that's not in the image.//// DASSERT(ix >= 0 && ix < Img.width && iy >= 0 && iy < Img.height);HFONT hFont;LOGFONT lf;if (iFontSize == 0) iFontSize = 80;hFont = EzCreateFont(hdcMem, "Times New Roman", iFontSize, 0, 0, true);GetObject(hFont, sizeof(LOGFONT), &lf);SelectObject(hdcMem, hFont);SetBkMode(hdcMem, TRANSPARENT);unsigned WindowsColor = (0xff & (Color >> 16)) | (0xff00 & Color) | (0xff0000 & (Color << 16));SetTextColor(hdcMem, WindowsColor);TextOut(hdcMem, ix, iy, s, strlen(s));DeleteObject(SelectObject(hdcMem, GetStockObject(SYSTEM_FONT)));ConvertRgbToWindowsHdc(Img, hdcMem, false);}//-----------------------------------------------------------------------------// Print text into an image, at image coords ix and iy// Use iFontSize==0 to get the default size// Current implementation is very slowvoid __cdecl RgbEllipse (RgbImage &Img, // io int iLeftRect, // in: x-coord of bounding rectangle's upper-left corner int iTopRect, // in: y-coord of bounding rectangle's upper-left corner int iRightRect, // in: x-coord of bounding rectangle's lower-right corner int iBottomRect, // in: y-coord of bounding rectangle's lower-right corner unsigned Red, unsigned Green, unsigned Blue) // in{if (Img.width % 4) { Warn("Can't draw ellipse into image because image width is not divisible by 4"); return; }HDC hdcMem;ConvertRgbToWindowsHdc(Img, hdcMem, true);unsigned WindowsColor = (0xff & Red) | (0xff00 & (Green << 8)) | (0xff0000 & (Blue << 16));HBRUSH hBrush = CreateSolidBrush(WindowsColor);hBrush = (HBRUSH)SelectObject(hdcMem, hBrush) ;Ellipse(hdcMem, iLeftRect, iTopRect, iRightRect, iBottomRect);DeleteObject(SelectObject(hdcMem, hBrush));ConvertRgbToWindowsHdc(Img, hdcMem, false);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -