// Image.cpp : implementation file // #include "stdafx.h" #include "Image.h" #include "FillQueue.h" #include "hDIB.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /****************************************************** »ý¼ºÀÚ, ÃʱâÈ­ ÇÔ¼ö ******************************************************/ CImage::CImage() { m_hImage = NULL; m_rgbLine.r = 0; m_rgbLine.g = 0; m_rgbLine.b = 1; } CImage::CImage(CImage &Src) { m_hImage = NULL; m_rgbLine.r = 0; m_rgbLine.g = 0; m_rgbLine.b = 1; *this = Src; } CImage::CImage(CBitmap &src) { m_hImage = NULL; m_rgbLine.r = 0; m_rgbLine.g = 0; m_rgbLine.b = 1; HDIB hImage = DDB2DIB(src); ConvertToImage(hImage); } CImage& CImage::operator=(CImage &src) // Right side is the argument. { // ÀÌÀü¿¡ À̹ÌÁö°¡ ÀÖ´Ù¸é Áö¿ö¾ß ÇÑ´Ù. Free(); // »õ·Î¿î À̹ÌÁö¸¦ °¡Á®¿Â´Ù. m_biHeader = src.GetHeader(); m_hImage = (HDIB) ::CopyHandle(src.GetHandle()); m_rgbMask = src.GetMaskColor(); m_rgbLine = src.GetLineColor(); return (*this); } // Function : CImage::Create // Descript : »õ·Î¿î À̹ÌÁö¸¦ »ý¼ºÇÑ´Ù. // Return : BOOL // Argument : long width // Argument : long height BOOL CImage::Create(long width, long height) { Free(); if (width == 0 || height == 0) return FALSE; DWORD dwSizeImage = height * (DWORD)((width * 3 + 3) & ~3); m_hImage = (HDIB) GlobalAlloc(GHND, dwSizeImage); if (m_hImage == NULL) return FALSE; m_biHeader.biSize = sizeof(BITMAPINFOHEADER); m_biHeader.biWidth = width; m_biHeader.biHeight = height; m_biHeader.biPlanes = 1; m_biHeader.biBitCount = 24; m_biHeader.biCompression = BI_RGB; m_biHeader.biSizeImage = dwSizeImage; m_biHeader.biXPelsPerMeter = 0; m_biHeader.biYPelsPerMeter = 0; m_biHeader.biClrUsed = 0; m_biHeader.biClrImportant = 0; return TRUE; } // Function : CImage::Free // Descript : À̹ÌÁö¸¦ ¹ÝȯÇÑ´Ù. // Return : void // Argument : void void CImage::Free() { // Delete image if (m_hImage) { if (GlobalFree(m_hImage) != NULL) { TRACE("Can't free handle in CImage::Free()"); } m_hImage = NULL; } } // Function : CImage::Draw // Descript : È®´ë/Ãà¼ÒÇÏÁö ¾Ê°í ¿øÇÏ´Â À§Ä¡¿¡ À̹ÌÁö¸¦ ±×¸°´Ù. // Return : BOOL // Argument : HDC hDC // Argument : long x // Argument : long y BOOL CImage::Draw(HDC hDC, long x, long y) { // ¸Þ¸ð¸® °íÁ¤ LPSTR address = (LPSTR) ::GlobalLock(m_hImage); ::SetStretchBltMode(hDC, COLORONCOLOR); // ¿ø·¡ Å©±â·Î ±×´ë·Î Ãâ·ÂÇÏ´Â °æ¿ì BOOL bSuccess = ::SetDIBitsToDevice(hDC, // hDC x, // DestX y, // DestY GetWidth(), // nDestWidth GetHeight(), // nDestHeight 0, // SrcX 0, // SrcY 0, // nStartScan GetHeight(), // nNumScans address, // lpBits (tagBITMAPINFO *)&m_biHeader, // lpBitsInfo DIB_RGB_COLORS); // wUsage // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); return bSuccess; } // Function : CImage::Draw // Descript : È®´ë/Ãà¼ÒÇÏ¿© ¿øÇÏ´Â À§Ä¡¿¡ À̹ÌÁö¸¦ ±×¸°´Ù. // Return : BOOL // Argument : HDC hDC // Argument : LPRECT lpDCRect BOOL CImage::Draw(HDC hDC, LPRECT lpDCRect) { BOOL bSuccess; // Success/fail Ç÷¡±× // ¸Þ¸ð¸® °íÁ¤ LPSTR address = (LPSTR) ::GlobalLock(m_hImage); ::SetStretchBltMode(hDC, COLORONCOLOR); bSuccess = ::StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight 0, // SrcX 0, // SrcY GetWidth(), // wSrcWidth GetHeight(), // wSrcHeight address, // lpBits (tagBITMAPINFO *)&m_biHeader, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); return bSuccess; } // Function : CImage::Draw // Descript : ÀÓÀÇÀÇ ºÎºÐÀ» È®´ë/Ãà¼ÒÇÏ¿© ¿øÇÏ´Â À§Ä¡¿¡ À̹ÌÁö¸¦ ±×¸°´Ù. // Return : BOOL // Argument : HDC hDC // Argument : LPRECT lpDIBRect // Argument : LPRECT lpDCRect BOOL CImage::Draw(HDC hDC, LPRECT lpDIBRect, LPRECT lpDCRect) { BOOL bSuccess; // Success/fail Ç÷¡±× // ¸Þ¸ð¸® °íÁ¤ LPSTR address = (LPSTR) ::GlobalLock(m_hImage); ::SetStretchBltMode(hDC, COLORONCOLOR); if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) // ¿ø·¡ Å©±â·Î ±×´ë·Î Ãâ·ÂÇÏ´Â °æ¿ì bSuccess = ::SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX GetHeight() - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan GetHeight(), // nNumScans address, // lpBits (tagBITMAPINFO *)&m_biHeader, // lpBitsInfo DIB_RGB_COLORS); // wUsage else // È®´ë ¶Ç´Â Ãà¼ÒÇÏ¿© Ãâ·ÂÇÏ´Â °æ¿ì bSuccess = ::StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight address, // lpBits (tagBITMAPINFO *)&m_biHeader, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); return bSuccess; } // Function : CImage::SetLineColor // Descript : »öä¿ì±â ½Ã º¯°æÇÒ ¼ö ¾ø´Â »ö»óÀ» ÁöÁ¤ÇÑ´Ù. // Return : void // Argument : BYTE r // Argument : BYTE g // Argument : BYTE b void CImage::SetLineColor(BYTE r, BYTE g, BYTE b) { m_rgbLine.r = r; m_rgbLine.g = g; m_rgbLine.b = b; } // Function : CImage::GetLineColor // Descript : »öä¿ì±â ½Ã º¯°æÇÒ ¼ö ¾ø´Â »ö»óÀ» °¡Á®¿Â´Ù. // Return : RGB // Argument : void RGBT CImage::GetLineColor() { return m_rgbLine; } // Function : CImage::CheckColor // Descript : º¯°æµÇ¾î¾ß ÇÏ´Â »ö»óÀÎÁö ¸®ÅÏÇÑ´Ù. // Return : BOOL // Argument : BYTE r // Argument : BYTE g // Argument : BYTE b BOOL CImage::CheckColor(BYTE r, BYTE g, BYTE b) { if (m_rgbMask.r == r && m_rgbMask.g == g && m_rgbMask.b == b) return TRUE; return FALSE; } // Function : CImage::SetMaskColor // Descript : º¯°æµÇ¾î¾ß ÇÏ´Â »ö»óÀ» Á¤ÇÑ´Ù. // Return : BOOL - º¯°æÇÒ ¼ö ¾ø´Â »ö»óÀÎ °æ¿ì FALSE // Argument : BYTE r // Argument : BYTE g // Argument : BYTE b BOOL CImage::SetMaskColor(BYTE r, BYTE g, BYTE b) { if (m_rgbLine.r == r && m_rgbLine.g == g && m_rgbLine.b == b) return FALSE; m_rgbMask.r = r; m_rgbMask.g = g; m_rgbMask.b = b; return TRUE; } // Function : CImage::GetMaskColor // Descript : º¯°æµÇ¾î¾ß ÇÏ´Â »ö»óÀ» °¡Á®¿Â´Ù. // Return : RGB // Argument : void RGBT CImage::GetMaskColor() { return m_rgbMask; } // Function : CImage::FillColor // Descript : À̹ÌÁö¿¡ ¿øÇÏ´Â »ö»óÀ¸·Î Ä¥ÇÑ´Ù. // Return : BOOL - À̹ÌÁö°¡ ¾ø°Å³ª Line »ö»óÀÎ °æ¿ì FALSE // Argument : long x, y - ±×¸± À§Ä¡ // Argument : BYTE r, g, b - Ä¥ÇÒ »ö»ó BOOL CImage::FillColor(long x, long y, BYTE r, BYTE g, BYTE b) { long tIndex; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return FALSE; BYTE * address = (BYTE *)::GlobalLock(m_hImage); // ±×¸®±â Áغñ. long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); // »ö ä¿ì±â °¡´ÉÇÑ°¡? y = dy - 1 - y; long index = (y * columns + x * 3); if (SetMaskColor(address[index + 2], address[index + 1], address[index]) == FALSE) { ::GlobalUnlock(m_hImage); return FALSE; } // ±âÁ¸ »ö»ó°ú Ä¥ÇÒ »ö»óÀÌ °°À¸¸é ¹«ÇÑ ·çÇÁ¿¡ ºüÁø´Ù!!! if (CheckColor(r, g, b)) { ::GlobalUnlock(m_hImage); return FALSE; } // »ö ä¿ì±â Pixel p; CFillQueue fQueue; fQueue.ClearQueue(); fQueue.Inqueue(x, y); while (fQueue.Dequeue(&p)) { // À̹ÌÁö¿¡¼­ÀÇ À§Ä¡¸¦ °è»ê index = (p.y * columns + p.x * 3); if (CheckColor(address[index + 2], address[index + 1], address[index])) { // À̹ÌÁö¿¡ ¿øÇÏ´Â »ö»óÀ» Ä¥ÇÑ´Ù. address[index + 2] = r; address[index + 1] = g; address[index ] = b; if ((p.y - 1) >= 0) { // Check Down-ward of Image tIndex = index - columns; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x, p.y - 1); } if ((p.x + 1) <= (dx - 1)) { // Check Right-ward of Image tIndex = index + 3; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x + 1, p.y); } if ((p.y + 1) <= (dy - 1)) { // Check Up-ward of Image tIndex = index + columns; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x, p.y + 1); } if ((p.x - 1) >= 0) { // Check Left-ward of Image tIndex = index - 3; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x - 1, p.y); } } } ::GlobalUnlock(m_hImage); return TRUE; } // Function : CImage::FillColor // Descript : À̹ÌÁö¿¡ ¿øÇÏ´Â ÆÐÅÏÀ̹ÌÁö·Î Ä¥ÇÑ´Ù. // - ±×¸®´Â ÆÐÅÏ À̹ÌÁöÀÇ »öÁß¿¡ ¹Ù²Ù°íÀÚÇÏ´Â »ö°ú // - °°Àº °ÍÀÌ ÀÖÀ¸¸é ¹«ÇÑ ·çÇÁ¿¡ ºüÁø´Ù. // Return : BOOL - À̹ÌÁö°¡ ¾ø°Å³ª Line »ö»óÀÎ °æ¿ì FALSE // Argument : long x, y - ±×¸± À§Ä¡ // Argument : CImage &image - ±×¸± ÆÐÅÏ BOOL CImage::FillColor(long x, long y, CImage &image) { long tIndex; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (image.GetHandle() == NULL) return FALSE; if (m_hImage == NULL) return FALSE; BYTE * address = (BYTE *)::GlobalLock(m_hImage); BYTE * src = (BYTE *)::GlobalLock(image.GetHandle()); long nStepX = image.GetWidth(); long nStepY = image.GetHeight(); // ±×¸®±â Áغñ. long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); // »ö ä¿ì±â °¡´ÉÇÑ°¡? y = dy - 1 - y; long index = (y * columns + x * 3); if (SetMaskColor(address[index + 2], address[index + 1], address[index]) == FALSE) { ::GlobalUnlock(m_hImage); return FALSE; } // »ö ä¿ì±â Pixel p; CFillQueue fQueue; fQueue.ClearQueue(); fQueue.Inqueue(x, y); while (fQueue.Dequeue(&p)) { // À̹ÌÁö¿¡¼­ÀÇ À§Ä¡¸¦ °è»ê index = (p.y * columns + p.x * 3); if (CheckColor(address[index + 2], address[index + 1], address[index])) { // À̹ÌÁö¿¡ ¿øÇÏ´Â »ö»óÀ» Ä¥ÇÑ´Ù. long nSrcX = p.x % nStepX; long nSrcY = p.y % nStepY; address[index + 2] = image.GetR(src, nSrcX, nSrcY); address[index + 1] = image.GetG(src, nSrcX, nSrcY); address[index ] = image.GetB(src, nSrcX, nSrcY); if ((p.y - 1) >= 0) { // Check Down-ward of Image tIndex = index - columns; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x, p.y - 1); } if ((p.x + 1) <= (dx - 1)) { // Check Right-ward of Image tIndex = index + 3; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x + 1, p.y); } if ((p.y + 1) <= (dy - 1)) { // Check Up-ward of Image tIndex = index + columns; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x, p.y + 1); } if ((p.x - 1) >= 0) { // Check Left-ward of Image tIndex = index - 3; if (CheckColor(address[tIndex + 2], address[tIndex + 1], address[tIndex])) fQueue.Inqueue(p.x - 1, p.y); } } } ::GlobalUnlock(image.GetHandle()); ::GlobalUnlock(m_hImage); return TRUE; } // Function : CImage::Mask // Descript : ƯÁ¤»öÀ» ¿øÇÏ´Â »öÀ¸·Î ¹Ù²Û´Ù. // Return : BOOL // Argument : BYTE r, g, b - Ä¥ÇÒ »ö»ó BOOL CImage::Mask(BYTE r, BYTE g, BYTE b) { long index, indexY; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return FALSE; BYTE * address = (BYTE *)::GlobalLock(m_hImage); // ÀÛ¾÷ÇÑ´Ù. long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); // Masking for (long y = 0; y < dy; y++) { indexY = y * columns; for (long x = 0; x < dx; x++) { index = indexY + x * 3; if (address[index + 2] == m_rgbMask.r && address[index + 1] == m_rgbMask.g && address[index] == m_rgbMask.b) { address[index + 2] = r; address[index + 1] = g; address[index ] = b; } } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); return TRUE; } // Function : CImage::MaskCopy // Descript : ƯÁ¤»ö ºÎºÐÀÇ À̹ÌÁö¸¦ °¡Á®¿Â´Ù. // Return : BOOL // Argument : BYTE r, g, b - ¸¶½ºÅ© »ö»ó, ±×¸®Áö ¾ÊÀ» »ö»ó // Argument : CImage &desImage - ´ë»ó À̹ÌÁö BOOL CImage::MaskCopy(BYTE r, BYTE g, BYTE b, CImage &desImage) { long index, indexY; long desIndex, desIndexY; if (desImage.GetHandle() == NULL) return FALSE; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return FALSE; BYTE * address = (BYTE *)::GlobalLock(m_hImage); BYTE * desAddress = (BYTE *)::GlobalLock(desImage.GetHandle()); // ÀÛ¾÷ÇÑ´Ù. long dy = __min(GetHeight(), desImage.GetHeight()); long dx = __min(GetWidth(), desImage.GetWidth()); long columns = GetRealWidth(); long desColumns = desImage.GetRealWidth(); // Masking for (long y = 0; y < dy; y++) { indexY = y * columns; desIndexY = y * desColumns; for (long x = 0; x < dx; x++) { index = x * 3; desIndex = index + desIndexY; index += indexY; if (address[index + 2] != r || address[index + 1] != g || address[index] != b) { desAddress[desIndex + 2] = address[index + 2]; desAddress[desIndex + 1] = address[index + 1]; desAddress[desIndex ] = address[index ]; } } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(desImage.GetHandle()); ::GlobalUnlock(m_hImage); return TRUE; } // Function : CImage::MaskCopy // Descript : Èò»ö°ú °ËÀº»öÀ» Á¦¿ÜÇÑ ¸ðµç ºÎºÐÀ» º¹»çÇÑ´Ù. // Return : BOOL // Argument : CImage &desImage - ´ë»ó À̹ÌÁö BOOL CImage::MaskCopy2(CImage &desImage) { long index, indexY; long desIndex, desIndexY; if (desImage.GetHandle() == NULL) return FALSE; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return FALSE; BYTE * address = (BYTE *)::GlobalLock(m_hImage); BYTE * desAddress = (BYTE *)::GlobalLock(desImage.GetHandle()); // ÀÛ¾÷ÇÑ´Ù. long dy = __min(GetHeight(), desImage.GetHeight()); long dx = __min(GetWidth(), desImage.GetWidth()); long columns = GetRealWidth(); long desColumns = desImage.GetRealWidth(); // Masking for (long y = 0; y < dy; y++) { indexY = y * columns; desIndexY = y * desColumns; for (long x = 0; x < dx; x++) { index = x * 3; desIndex = index + desIndexY; index += indexY; if (address[index + 2] == 0 && address[index + 1] == 0 && address[index] == 0) { // À̹ÌÁö Áß¿¡ Èñ»öºÎºÐÀ» ¹è¿ì±â À§ÇÔÀÌ´Ù. long temp; // x, y - 1 temp = index - columns; if ((y > 0) && (address[temp + 2] != 0 || address[temp + 1] != 0 || address[temp] != 0) && (address[temp + 2] != 255 || address[temp + 1] != 255 || address[temp] != 255)) { desAddress[desIndex + 2] = address[temp + 2] >> 1; desAddress[desIndex + 1] = address[temp + 1] >> 1; desAddress[desIndex ] = address[temp ] >> 1; } else { // x + 1, y temp = index + 3; if ((dx - 1 > x) && (address[temp + 2] != 0 || address[temp + 1] != 0 || address[temp] != 0) && (address[temp + 2] != 255 || address[temp + 1] != 255 || address[temp] != 255)) { desAddress[desIndex + 2] = address[temp + 2] >> 1; desAddress[desIndex + 1] = address[temp + 1] >> 1; desAddress[desIndex ] = address[temp ] >> 1; } else { // x, y + 1 temp = index + columns; if ((dy - 1 > y) && (address[temp + 2] != 0 || address[temp + 1] != 0 || address[temp] != 0) && (address[temp + 2] != 255 || address[temp + 1] != 255 || address[temp] != 255)) { desAddress[desIndex + 2] = address[temp + 2] >> 1; desAddress[desIndex + 1] = address[temp + 1] >> 1; desAddress[desIndex ] = address[temp ] >> 1; } else { // x - 1, y temp = index - 3; if ((x > 0) && (address[temp + 2] != 0 || address[temp + 1] != 0 || address[temp] != 0) && (address[temp + 2] != 255 || address[temp + 1] != 255 || address[temp] != 255)) { desAddress[desIndex + 2] = address[temp + 2] >> 1; desAddress[desIndex + 1] = address[temp + 1] >> 1; desAddress[desIndex ] = address[temp ] >> 1; } } } } } else if (address[index + 2] != 255 || address[index + 1] != 255 || address[index] != 255) { desAddress[desIndex + 2] = address[index + 2]; desAddress[desIndex + 1] = address[index + 1]; desAddress[desIndex ] = address[index ]; } } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(desImage.GetHandle()); ::GlobalUnlock(m_hImage); return TRUE; } // Function : CImage::Treshold // Descript : À̹ÌÁö¸¦ ´Ü¼øÈ­ ÇÑ´Ù. // Return : void // Argument : long nTreshold - °æ°è°ª void CImage::Treshold(long nThreshold) { long index, indexY; long r, g, b; BYTE intensity; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return ; BYTE * address = (BYTE *)::GlobalLock(m_hImage); // ÀÛ¾÷ÇÑ´Ù. long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); // Masking for (long y = 0; y < dy; y++) { indexY = y * columns; for (long x = 0; x < dx; x++) { index = indexY + x * 3; r = (long)(address[index + 2]); g = (long)(address[index + 1]); b = (long)(address[index + 0]); intensity = (BYTE)((r + g + b) / 3); if (intensity > nThreshold) intensity = 255; else intensity = 0; address[index + 2] = intensity; address[index + 1] = intensity; address[index ] = intensity; } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); return ; } // ¸Þ¸ð¸® ¶ôµÈ °æ¿ì¸¦ °¡Á¤ÇÑ´Ù. BYTE CImage::GetB(BYTE *address, long x, long y) { long index = y*GetRealWidth() + x*3; return address[index]; } // ¸Þ¸ð¸® ¶ôµÈ °æ¿ì¸¦ °¡Á¤ÇÑ´Ù. BYTE CImage::GetG(BYTE *address, long x, long y) { long index = y*GetRealWidth() + x*3 + 1; return address[index]; } // ¸Þ¸ð¸® ¶ôµÈ °æ¿ì¸¦ °¡Á¤ÇÑ´Ù. BYTE CImage::GetR(BYTE *address, long x, long y) { long index = y*GetRealWidth() + x*3 + 2; return address[index]; } /****************************************************** ÆÄÀÏ Àоî¿À±â, ÀúÀåÇϱ⠽ÇÁ¦ ±×·¡ÇÈ ÆÄÀÏÀ» Àоî¿À´Â ·çƾÀº ´ÙÀ½ ÆÄÀÏ¿¡ ÀÖÀ½ ImageBmp.cpp : BMP ÆÄÀÏ (LoadBMP, SaveBMP) ImageGif.cpp : GIF ÆÄÀÏ (LoadGIF, SaveGIF) ImageJpg.cpp : JPEG ÆÄÀÏ (LoadJPG, SaveJPG) ******************************************************/ // Function : CImage::Save // Descript : À̹ÌÁö¸¦ ¿øÇÏ´Â Æ÷¸ËÀ¸·Î ÀúÀåÇÑ´Ù. // Return : BOOL - Áö¿øÇÏÁö ¾Ê´Â À̹ÌÁö Æ÷¸ËÀ̶ó¸é FALSE // Argument : LPCTSTR lpszFileName - ÀúÀåÇÒ À̹ÌÁö ¸í BOOL CImage::Save(LPCTSTR lpszFileName) { CString szFileType; szFileType = lpszFileName; szFileType.MakeLower(); if (szFileType.Find(".bmp") > -1) return SaveBMP(lpszFileName); // else if (szFileType.Find(".gif") > -1) // return SaveGIF(lpszFileName); else if (szFileType.Find(".jpg") > -1) return SaveJPG(lpszFileName); return FALSE; } // Function : CImage::Load // Descript : À̹ÌÁö¸¦ °¡Á®¿À¸ç Æ÷¸Ë¿¡ µû¶ó ÇÊ¿äÇÔ¼ö È£ÃâÇÑ´Ù. // Return : BOOL - Áö¿øÇÏÁö ¾Ê´Â À̹ÌÁö Æ÷¸ËÀ̶ó¸é FALSE // Argument : LPCTSTR lpszFileName - °¡Á®¿Ã À̹ÌÁö ¸í BOOL CImage::Load(LPCTSTR lpszFileName) { CString szFileType; szFileType = lpszFileName; szFileType.MakeLower(); if (szFileType.Find(".bmp") > -1) { Free(); return LoadBMP(lpszFileName); } else if (szFileType.Find(".gif") > -1) { Free(); return LoadGIF(lpszFileName); } else if (szFileType.Find(".jpg") > -1) { Free(); return LoadJPG(lpszFileName); } return FALSE; } // Function : CopyHandle // Descript : À̹ÌÁö ÇÚµéÀ» º¹»ç ÇÑ´Ù. // Return : HGLOBAL - º¹»çµÈ ÇÚµé // Argument : HGLOBAL hHandle HGLOBAL WINAPI CopyHandle(HGLOBAL hHandle) { if (hHandle == NULL) return NULL; DWORD dwLen = ::GlobalSize( hHandle); HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen); if (hCopy != NULL) { void* lpCopy = ::GlobalLock( hCopy); void* lp = ::GlobalLock( hHandle); memcpy(lpCopy, lp, dwLen); ::GlobalUnlock(hCopy); ::GlobalUnlock(hHandle); } return hCopy; } void CImage::Zoom(long width, long height) { if (m_hImage == NULL) return ; if (height > GetHeight()) { CImage newImage; if (newImage.Create(GetWidth(), height)) { // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. BYTE * srcAddress = (BYTE *)::GlobalLock(m_hImage); BYTE * desAddress = (BYTE *)::GlobalLock(newImage.GetHandle()); // copy source image long dx = GetWidth(); long dy = GetHeight(); long columns = GetRealWidth(); for (long y = 0; y < dy; y++) { long index; long indexY = y * columns; for (long x = 0; x < dx; x++) { index = indexY + x * 3; // RGB Model desAddress[index] = srcAddress[index]; index++; desAddress[index] = srcAddress[index]; index++; desAddress[index] = srcAddress[index]; } } ZoomInY(desAddress, GetWidth(), GetHeight(), height); // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(newImage.GetHandle()); ::GlobalUnlock(m_hImage); *this = newImage; } } if (width > GetWidth()) { CImage newImage; if (newImage.Create(width, GetHeight())) { // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. BYTE * srcAddress = (BYTE *)::GlobalLock(m_hImage); BYTE * desAddress = (BYTE *)::GlobalLock(newImage.GetHandle()); // copy source image long dx = GetWidth(); long dy = GetHeight(); long columns = GetRealWidth(); long columnsT = newImage.GetRealWidth(); for (long y = 0; y < dy; y++) { long index; long indexT; long indexY = y * columns; long indexTY = y * columnsT; for (long x = 0; x < dx; x++) { index = x * 3; indexT = indexTY + index; index += indexY; // RGB Model desAddress[indexT] = srcAddress[index]; index++; indexT++; desAddress[indexT] = srcAddress[index]; index++; indexT++; desAddress[indexT] = srcAddress[index]; } } ZoomInX(desAddress, GetWidth(), GetHeight(), width); // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(newImage.GetHandle()); ::GlobalUnlock(m_hImage); *this = newImage; } } if (GetHeight() > height) { // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. BYTE * address = (BYTE *)::GlobalLock(m_hImage); CImage *pImage = ZoomOutY(address, GetWidth(), GetHeight(), height); // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); if (pImage != NULL) { *this = *pImage; delete pImage; } } if (GetWidth() > width) { // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. BYTE * address = (BYTE *)::GlobalLock(m_hImage); CImage *pImage = ZoomOutX(address, GetWidth(), GetHeight(), width); // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); if (pImage != NULL) { *this = *pImage; delete pImage; } } } void CImage::ZoomInY(BYTE * desImage, long sdx, long sdy, long ddy) { if (sdy > ddy) return ; // variable for Zoom-In long x, y; long index, indexY; long ty; // temporary for work long indexT, indexTY; BYTE r, g, b; BYTE rr, rg, rb; long ody = sdy; long tdy = sdy; long columns = (sdx * 3 + 3) & ~3; double scaleY = (double)ddy / (double)sdy; // (scale / 2) * (2) // Y axis while (scaleY >= 2) // case scale(2) { scaleY /= 2; tdy <<= 1; ty = tdy - 1; y = ody - 1; indexY = y * columns; indexTY = ty * columns; for (x = 0; x < sdx; x++) { indexT = x * 3; index = indexY + indexT; indexT += indexTY; // BGR ¼øÀ¸·Î º¹»ç desImage[indexT] = desImage[index]; indexT++; index++; desImage[indexT] = desImage[index]; indexT++; index++; desImage[indexT] = desImage[index]; } for (y--, ty--; y >= 0; y--, ty -= 2) { indexY = y * columns; indexTY = ty * columns; for (x = 0; x < sdx; x++) { indexT = x * 3; index = indexY + indexT; // RGB Model b = desImage[index]; rb = desImage[index + columns]; index++; g = desImage[index]; rg = desImage[index + columns]; index++; r = desImage[index]; rr = desImage[index + columns]; rr = (BYTE)(((int)rr + (int)r) >> 1); rg = (BYTE)(((int)rg + (int)g) >> 1); rb = (BYTE)(((int)rb + (int)b) >> 1); indexT += indexTY; desImage[indexT] = rb; desImage[indexT - columns] = b; indexT++; desImage[indexT] = rg; desImage[indexT - columns] = g; indexT++; desImage[indexT] = rr; desImage[indexT - columns] = r; } } ody = tdy; } if (scaleY > 1) // case scale(1.x) { long nSingleDy = tdy; long nDoubleDy = tdy << 1; long step = nDoubleDy; tdy = ddy; ty = tdy - 1; for (y = ody - 1; y >= 0; y--) { step -= ddy; if (step <= 0) { indexY = y * columns; indexTY = ty * columns; for (x = 0; x < sdx; x++) { indexT = x * 3; index = indexY + indexT; // RGB Model b = desImage[index]; rb = desImage[index + columns]; index++; g = desImage[index]; rg = desImage[index + columns]; index++; r = desImage[index]; rr = desImage[index + columns]; rr = (BYTE)(((int)rr + (int)r) >> 1); rg = (BYTE)(((int)rg + (int)g) >> 1); rb = (BYTE)(((int)rb + (int)b) >> 1); indexT += indexTY; desImage[indexT] = rb; desImage[indexT - columns] = b; indexT++; desImage[indexT] = rg; desImage[indexT - columns] = g; indexT++; desImage[indexT] = rr; desImage[indexT - columns] = r; } ty -= 2; step += nDoubleDy; } else { indexY = y * columns; indexTY = ty * columns; for (x = 0; x < sdx; x++) { indexT = x * 3; index = indexY + indexT; indexT += indexTY; // BGR ¼øÀ¸·Î º¹»ç desImage[indexT] = desImage[index]; indexT++; index++; desImage[indexT] = desImage[index]; indexT++; index++; desImage[indexT] = desImage[index]; } ty--; step += nSingleDy; } } } } void CImage::ZoomInX(BYTE * desImage, long sdx, long sdy, long ddx) { if (sdx > ddx) return ; // variable for Zoom-In long index, indexT; long indexY; long x, y; long indexX, indexTX; long tx; // temporary for work BYTE r, g, b; BYTE rr, rg, rb; long odx = sdx; long tdx = sdx; long columns = (ddx * 3 + 3) & ~3; double scaleX = (double)ddx / (double)sdx; // X axis while (scaleX >= 2) // case scale(2) { scaleX /= 2; tdx <<= 1; tx = tdx - 1; x = odx - 1; indexX = x * 3; indexTX = tx * 3; for (y = 0; y < sdy; y++) { // RGB Model indexY = y * columns; index = indexX + indexY; indexT = indexTX + indexY; desImage[indexT + 2] = desImage[index + 2]; desImage[indexT + 1] = desImage[index + 1]; desImage[indexT ] = desImage[index ]; } for (x--, tx--; x >= 0; x--, tx -= 2) { indexX = x * 3; indexTX = tx * 3; for (y = 0; y < sdy; y++) { indexY = y * columns; index = indexX + indexY; // RGB Model r = desImage[index + 2]; g = desImage[index + 1]; b = desImage[index + 0]; rr = desImage[index + 3 + 2]; rg = desImage[index + 3 + 1]; rb = desImage[index + 3 + 0]; rr = (BYTE)(((int)rr + (int)r) >> 1); rg = (BYTE)(((int)rg + (int)g) >> 1); rb = (BYTE)(((int)rb + (int)b) >> 1); index = indexTX + indexY; desImage[index + 2] = rr; desImage[index + 1] = rg; desImage[index + 0] = rb; desImage[index - 3 + 2] = r; desImage[index - 3 + 1] = g; desImage[index - 3 + 0] = b; } } odx = tdx; } if (scaleX > 1) // case scale(1.x) { long nSingleDx = tdx; long nDoubleDx = tdx << 1; long step = nDoubleDx; tdx = ddx; tx = tdx - 1; for (x = odx - 1; x >= 0; x--) { step -= ddx; if (step <= 0) { indexX = x * 3; indexTX = tx * 3; for (y = 0; y < sdy; y++) { indexY = y * columns; index = indexX + indexY; // RGB Model r = desImage[index + 2]; g = desImage[index + 1]; b = desImage[index ]; rr = desImage[index + 3 + 2]; rg = desImage[index + 3 + 1]; rb = desImage[index + 3 ]; rr = (BYTE)(((int)rr + (int)r) >> 1); rg = (BYTE)(((int)rg + (int)g) >> 1); rb = (BYTE)(((int)rb + (int)b) >> 1); index = indexTX + indexY; desImage[index + 2] = rr; desImage[index + 1] = rg; desImage[index ] = rb; desImage[index - 3 + 2] = r; desImage[index - 3 + 1] = g; desImage[index - 3 ] = b; } tx -= 2; step += nDoubleDx; } else { indexX = x * 3; indexTX = tx * 3; for (y = 0; y < sdy; y++) { indexY = y * columns; index = indexX + indexY; indexT = indexTX + indexY; // RGB Model desImage[indexT + 2] = desImage[index + 2]; desImage[indexT + 1] = desImage[index + 1]; desImage[indexT + 0] = desImage[index + 0]; } tx--; step += nSingleDx; } } } } CImage * CImage::ZoomOutY(BYTE *srcImage, long dx, long dy, long ddy) { long x; double y; long index, indexY; CImage * pImage = new CImage; if (pImage->Create(dx, ddy) == FALSE) return NULL; BYTE * desImage = (BYTE *)::GlobalLock(pImage->GetHandle()); // ÀÛ¾÷ÇÑ´Ù. long columns = (dx * 3 + 3) & ~3; // variable for Zoom-Out long ty; // temporary for work long indexX; double sy; double ey; long count; BYTE r, g, b; int sumR, sumG, sumB; double scaleY = (double)dy / (double)ddy; // Y axis sy = 0; ey = scaleY / 2; for (x = 0; x < dx; x++) { indexX = x * 3; sumR = 0; sumG = 0; sumB = 0; count = 0; for (y = sy; y < ey; y++) { index = (long)y * columns + indexX; // RGB Model r = (BYTE)srcImage[index + 2]; g = (BYTE)srcImage[index + 1]; b = (BYTE)srcImage[index + 0]; sumR += r; sumG += g; sumB += b; count++; } desImage[indexX + 2] = (BYTE)(sumR / count); desImage[indexX + 1] = (BYTE)(sumG / count); desImage[indexX + 0] = (BYTE)(sumB / count); } for (ty = 1; ty < ddy; ty++) { sy = ey; ey += scaleY; indexY = ty * columns; for (x = 0; x < dx; x++) { indexX = x * 3; sumR = 0; sumG = 0; sumB = 0; count = 0; for (y = sy; y < ey && y < dy; y++) { index = (long)y * columns + indexX; // RGB Model r = (BYTE)srcImage[index + 2]; g = (BYTE)srcImage[index + 1]; b = (BYTE)srcImage[index + 0]; sumR += r; sumG += g; sumB += b; count++; } index = indexY + indexX; desImage[index + 2] = (BYTE)(sumR / count); desImage[index + 1] = (BYTE)(sumG / count); desImage[index + 0] = (BYTE)(sumB / count); } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(pImage->GetHandle()); return pImage; } CImage *CImage::ZoomOutX(BYTE *srcImage, long dx, long dy, long ddx) { double x; long y; long index, indexY; CImage *pImage = new CImage; if (pImage->Create(ddx, dy) == FALSE) return NULL; BYTE * desImage = (BYTE *)::GlobalLock(pImage->GetHandle()); // ÀÛ¾÷ÇÑ´Ù. long columns = (dx * 3 + 3) & ~3; long columnsT = (ddx * 3 + 3) & ~3; // variable for Zoom-Out long tx; // temporary for work long indexX; double sx; double ex; long count; BYTE r, g, b; int sumR, sumG, sumB; double scaleX = (double)dx / (double)ddx; // X axis sx = 0; ex = scaleX / 2; indexX = 0; for (y = 0; y < dy; y++) { indexY = y * columns; sumR = 0; sumG = 0; sumB = 0; count = 0; for (x = sx; x < ex; x++) { index = indexY + (long)x * 3; // RGB Model r = (BYTE)srcImage[index + 2]; g = (BYTE)srcImage[index + 1]; b = (BYTE)srcImage[index + 0]; sumR += r; sumG += g; sumB += b; count++; } index = y * columnsT + indexX; desImage[index + 2] = (BYTE)(sumR / count); desImage[index + 1] = (BYTE)(sumG / count); desImage[index + 0] = (BYTE)(sumB / count); } for (tx = 1; tx < ddx; tx++) { sx = ex; ex += scaleX; indexX = tx * 3; for (y = 0; y < dy; y++) { indexY = y * columns; sumR = 0; sumG = 0; sumB = 0; count = 0; for (x = sx; x < ex && x < dx; x++) { index = indexY + (long)x * 3; // RGB Model r = (BYTE)srcImage[index + 2]; g = (BYTE)srcImage[index + 1]; b = (BYTE)srcImage[index + 0]; sumR += r; sumG += g; sumB += b; count++; } index = y * columnsT + indexX; desImage[index + 2] = (BYTE)(sumR / count); desImage[index + 1] = (BYTE)(sumG / count); desImage[index + 0] = (BYTE)(sumB / count); } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(pImage->GetHandle()); return pImage; } void CImage::ColorRound(COLORREF crTarget, COLORREF crRound, long nSize) { long index, indexY; long temp; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return ; BYTE * address = (BYTE *)::GlobalLock(m_hImage); m_pAddress = address; // ÀÛ¾÷ÇÑ´Ù. long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); // ÀÌ»öÀÇ Å׵θ®¸¦ Ä¥ÇÏ°Ô µÈ´Ù. m_sr = GetRValue(crTarget); m_sg = GetGValue(crTarget); m_sb = GetBValue(crTarget); m_dr = GetRValue(crRound); m_dg = GetGValue(crRound); m_db = GetBValue(crRound); // Masking for (long y = 0; y < dy; y++) { indexY = y * columns; for (long x = 0; x < dx; x++) { index = indexY + x * 3; if (address[index + 2] == m_sr && address[index + 1] == m_sg && address[index] == m_sb) { // ÀÌ¿ôÇÏ´Â Á¡ÀÇ »ö»óÀ» °Ë»çÇØ ÆÐÅÏÀ» ã¾Æ³½´Ù. long nMask = 0x00ff; // x, y - 1 temp = index - columns; if ((y <= 0) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x00f8; else { // x - 1, y - 1 temp -= 3; if ((x <= 0) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x00f8; } // x + 1, y temp = index + 3; if ((dx - 1 <= x) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x00e3; else { // x + 1, y - 1 temp -= columns; if ((y <= 0) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x00e3; } // x, y + 1 temp = index + columns; if ((dy - 1 <= y) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x008f; else { // x + 1, y + 1 temp += 3; if ((dx - 1 <= x) || address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb) nMask &= 0x008f; } // x - 1, y temp = index - 3; if ((x <= 0) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x003e; else { // x - 1, y + 1 temp += columns; if ((y <= 0) || (address[temp + 2] == m_sr && address[temp + 1] == m_sg && address[temp] == m_sb)) nMask &= 0x003e; } // Áß°£¿¡ ÀÖ´Â °æ¿ì¸¦ À§ÇØ m_nIndex = index + 3; DrawPixel(); if (nMask) { // draw pattern if (nMask & 1) { CircleQuad1(address, x, y, nSize); } if (nMask & 2) { m_nIndex = index; for (long i = 0; i < nSize && y-i >= 0; i++) { m_nIndex -= columns; DrawPixel(); } } if (nMask & 4) { CircleQuad2(address, x, y, nSize); } if (nMask & 8) { m_nIndex = index; for (long i = 0; i < nSize && x+i < dx; i++) { m_nIndex += 3; DrawPixel(); } } if (nMask & 16) { CircleQuad3(address, x, y, nSize); } if (nMask & 32) { m_nIndex = index; for (long i = 0; i < nSize && y+i < dy; i++) { m_nIndex += columns; DrawPixel(); } } if (nMask & 64) { CircleQuad4(address, x, y, nSize); } if (nMask & 128) { m_nIndex = index; for (long i = 0; i < nSize && x-i >= 0; i++) { m_nIndex -= 3; DrawPixel(); } } } } } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); } void CImage::CircleQuad1(BYTE *address, long nCenterX, long nCenterY, long radius) { long x = 0; long y = radius; long p = 1 - radius; long prev1 = -1; long prev2 = -1; long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); m_pAddress = address; while (x < y) { x++; if (p < 0) p += 2 * x + 1; else { y--; p += 2 * (x-y) + 1; } if (prev1 != x) { prev1 = x; m_nIndex = (nCenterY-x) * columns + (nCenterX) * 3; for (long i = 0; i < y && nCenterX-i >= 0; i++) { m_nIndex -= 3; DrawPixel(); } // putpixel(nCenterX-y, nCenterY-x); } if (prev2 != y) { prev2 = y; m_nIndex = (nCenterY-y) * columns + (nCenterX) * 3; for (long i = 0; i < x && nCenterX-i >= 0; i++) { m_nIndex -= 3; DrawPixel(); } // putpixel(nCenterX-x, nCenterY-y); } } } void CImage::CircleQuad2(BYTE *address, long nCenterX, long nCenterY, long radius) { long x = 0; long y = radius; long p = 1 - radius; long prev1 = -1; long prev2 = -1; long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); m_pAddress = address; while (x < y) { x++; if (p < 0) p += 2 * x + 1; else { y--; p += 2 * (x-y) + 1; } if (prev1 != y) { prev1 = y; m_nIndex = (nCenterY-y) * columns + (nCenterX) * 3; for (long i = 0; i < x && nCenterX+i < dx; i++) { m_nIndex += 3; DrawPixel(); } // putpixel(nCenterX+x, nCenterY-y); } if (prev2 != x) { prev2 = x; m_nIndex = (nCenterY-x) * columns + (nCenterX) * 3; for (long i = 0; i < y && nCenterX+i < dx; i++) { m_nIndex += 3; DrawPixel(); } // putpixel(nCenterX+y, nCenterY-x); } } } void CImage::CircleQuad3(BYTE *address, long nCenterX, long nCenterY, long radius) { long x = 0; long y = radius; long p = 1 - radius; long prev1 = -1; long prev2 = -1; long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); m_pAddress = address; while (x < y) { x++; if (p < 0) p += 2 * x + 1; else { y--; p += 2 * (x-y) + 1; } if (prev1 != x) { prev1 = x; m_nIndex = (nCenterY+x) * columns + (nCenterX) * 3; for (long i = 0; i < y && nCenterX+i < dx; i++) { m_nIndex += 3; DrawPixel(); } // putpixel(nCenterX+y, nCenterY+x); } if (prev2 != y) { prev2 = y; m_nIndex = (nCenterY+y) * columns + (nCenterX) * 3; for (long i = 0; i < x && nCenterX+i < dx; i++) { m_nIndex += 3; DrawPixel(); } // putpixel(nCenterX+x, nCenterY+y); } } } void CImage::CircleQuad4(BYTE *address, long nCenterX, long nCenterY, long radius) { long x = 0; long y = radius; long p = 1 - radius; long prev1 = -1; long prev2 = -1; long dy = GetHeight(); long dx = GetWidth(); long columns = GetRealWidth(); m_pAddress = address; while (x < y) { x++; if (p < 0) p += 2 * x + 1; else { y--; p += 2 * (x-y) + 1; } if (prev1 != y) { prev1 = y; m_nIndex = (nCenterY+y) * columns + (nCenterX) * 3; for (long i = 0; i < x && nCenterX-i >= 0; i++) { m_nIndex -= 3; DrawPixel(); } // putpixel(nCenterX-x, nCenterY+y); } if (prev2 != x) { prev2 = x; m_nIndex = (nCenterY+x) * columns + (nCenterX) * 3; for (long i = 0; i < y && nCenterX-i >= 0; i++) { m_nIndex -= 3; DrawPixel(); } // putpixel (nCenterX-y, nCenterY+x); } } } void CImage::DrawPixel() { if (m_pAddress[m_nIndex + 2] != m_sr || m_pAddress[m_nIndex + 1] != m_sg || m_pAddress[m_nIndex] != m_sb) { m_pAddress[m_nIndex + 2] = m_dr; m_pAddress[m_nIndex + 1] = m_dg; m_pAddress[m_nIndex ] = m_db; } } void CImage::ScrollImage(CImage &image, long nStartY, long nEndY) { image.Zoom(GetWidth(), GetHeight()); // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return ; BYTE * address = (BYTE *)::GlobalLock(m_hImage); // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); } void CImage::Blur() { long index, indexY; // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return ; BYTE * address = (BYTE *)::GlobalLock(m_hImage); CImage image = *this; BYTE * src = (BYTE *)::GlobalLock(image.GetHandle()); // ÀÛ¾÷ÇÑ´Ù. long dy = GetHeight() - 1; long dx = GetWidth() - 1; long columns = GetRealWidth(); // Masking for (long y = 1; y < dy; y++) { indexY = y * columns; for (long x = 1; x < dx; x++) { index = indexY + x * 3; address[index] = (BYTE)(((int)src[index-columns] + src[index-3] + src[index] + src[index+3] + src[index+columns]) / 5); index++; address[index] = (BYTE)(((int)src[index-columns] + src[index-3] + src[index] + src[index+3] + src[index+columns]) / 5); index++; address[index] = (BYTE)(((int)src[index-columns] + src[index-3] + src[index] + src[index+3] + src[index+columns]) / 5); } } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(image.GetHandle()); ::GlobalUnlock(m_hImage); return ; } COLORREF CImage::GetColor(long x, long y) { // ÀÛ¾÷ÇÒ À̹ÌÁö¸¦ ½ºÅÿ¡¼­ °¡Áö°í ¿Â´Ù. if (m_hImage == NULL) return 0; BYTE * address = (BYTE *)::GlobalLock(m_hImage); long index = y * GetRealWidth() + x * 3; BYTE r = address[index + 2]; BYTE g = address[index + 1]; BYTE b = address[index ]; // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(m_hImage); return RGB(r, g, b); } // !±âÁ¸ÀÇ À̹ÌÁö¸¦ ¸ðµÎ Áö¿î´Ù. void CImage::FillSide(long nMode, long nSize, CImage &image) { if (image.GetHandle() == NULL) return ; if (nMode == 1 || nMode == 2) { if (Create(image.GetWidth(), nSize)) { BYTE * address = (BYTE *)::GlobalLock(m_hImage); BYTE * src = (BYTE *)::GlobalLock(image.GetHandle()); long columns = GetRealWidth(); long indexT = 0; if (nMode == 1) indexT = (image.GetHeight() - 1) * columns; for (long i = 0; i < nSize; i++) { long index = i * columns; memcpy(address+index, src+indexT, columns); } // ¸Þ¸ð¸® ³õ¾ÆÁÜ ::GlobalUnlock(image.GetHandle()); ::GlobalUnlock(m_hImage); } } }