📄 gimage.cpp
字号:
GColor c1; GColor c2; int x, y; int nHalfHeight = (int)m_nHeight >> 1; for(x = 0; x < (int)m_nWidth; x++) { for(y = 0; y < nHalfHeight; y++) { c1 = GetPixel(x, y); c2 = GetPixel(x, m_nHeight - 1 - y); SetPixel(x, y, c2); SetPixel(x, m_nHeight - 1 - y, c1); } }}void GImage::SwapData(GImage* pSwapImage){ GColor* pTmpRGBQuads = m_pPixels; unsigned int nTmpWidth = m_nWidth; unsigned int nTmpHeight = m_nHeight; m_pPixels = pSwapImage->m_pPixels; m_nWidth = pSwapImage->m_nWidth; m_nHeight = pSwapImage->m_nHeight; pSwapImage->m_pPixels = pTmpRGBQuads; pSwapImage->m_nWidth = nTmpWidth; pSwapImage->m_nHeight = nTmpHeight;}void GImage::Convolve(GImage* pKernel){ GImage NewImage; NewImage.SetSize(m_nWidth, m_nHeight); GColor c1; GColor c2; int nHalfKWidth = (int)pKernel->m_nWidth >> 1; int nHalfKHeight = (int)pKernel->m_nHeight >> 1; int nRSum, nGSum, nBSum; int nRTot, nGTot, nBTot; nRTot = 0; nGTot = 0; nBTot = 0; int x, y, kx, ky; for(ky = 0; ky < (int)pKernel->m_nHeight; ky++) { for(kx = 0; kx < (int)pKernel->m_nWidth; kx++) { c1 = pKernel->GetPixel(kx, ky); nRTot += gRed(c1); nGTot += gGreen(c1); nBTot += gBlue(c1); } } nRTot = MAX(1, nRTot); nGTot = MAX(1, nGTot); nBTot = MAX(1, nBTot); for(y = 0; y < (int)m_nHeight; y++) { for(x = 0; x < (int)m_nWidth; x++) { nRSum = 0; nGSum = 0; nBSum = 0; for(ky = 0; ky < (int)pKernel->m_nHeight; ky++) { for(kx = 0; kx < (int)pKernel->m_nWidth; kx++) { c1 = pKernel->GetPixel(pKernel->m_nWidth - kx - 1, pKernel->m_nHeight - ky - 1); c2 = SafeGetPixel(x + kx - nHalfKWidth, y + ky - nHalfKHeight); nRSum += gRed(c1) * gRed(c2); nGSum += gGreen(c1) * gGreen(c2); nBSum += gBlue(c1) * gBlue(c2); } } NewImage.SetPixel(x, y, gRGB(ClipChan(nRSum / nRTot), ClipChan(nGSum / nGTot), ClipChan(nBSum / nBTot))); } } SwapData(&NewImage);}void GImage::ConvolveKernel(GImage* pKernel){ GImage NewImage; NewImage.SetSize(m_nWidth, m_nHeight); GColor c1; GColor c2; int nHalfKWidth = (int)pKernel->m_nWidth >> 1; int nHalfKHeight = (int)pKernel->m_nHeight >> 1; int nRSum, nGSum, nBSum; int x, y; int kx, ky; for(y = 0; y < (int)m_nHeight; y++) { for(x = 0; x < (int)m_nWidth; x++) { nRSum = 0; nGSum = 0; nBSum = 0; for(ky = 0; ky < (int)pKernel->m_nHeight; ky++) { for(kx = 0; kx < (int)pKernel->m_nWidth; kx++) { c1 = pKernel->GetPixel(pKernel->m_nWidth - kx - 1, pKernel->m_nHeight - ky - 1); c2 = SafeGetPixel(x + kx - nHalfKWidth, y + ky - nHalfKHeight); nRSum += gRed(c1) * gRed(c2); nGSum += gGreen(c1) * gGreen(c2); nBSum += gBlue(c1) * gBlue(c2); } } nRSum = ClipChan(nRSum); nGSum = ClipChan(nGSum); nBSum = ClipChan(nBSum); NewImage.SetPixel(x, y, gRGB(nRSum, nGSum, nBSum)); } } SwapData(&NewImage);}void GImage::Blur(double dRadius){ // Calculate how big of a kernel we need int nFactor = (int)dRadius; int nWidth = nFactor * 2 + 1; GImage imgKernel; imgKernel.SetSize(nWidth, nWidth); // Produce the blurring kernel double dTmp = dRadius / 8; double d; int n; int x, y; for(y = 0; y < nWidth; y++) { for(x = 0; x < nWidth; x++) { d = pow((double)2, -(sqrt((double)((nFactor - x) * (nFactor - x) + (nFactor - y) * (nFactor - y))) / dTmp)); n = ClipChan((int)(d * 256)); imgKernel.SetPixel(x, y, gRGB(n, n, n)); } } // Convolve the kernel with the image Convolve(&imgKernel);}void GImage::QuickBlur(int nRadius){ GImage tmp; tmp.SetSize(GetWidth(), GetHeight()); int x, y, i, r, g, b, head, tail; GColor c; for(y = 0; y < m_nHeight; y++) { for(x = 0; x < m_nWidth; x++) { r = 0; g = 0; b = 0; head = MAX(0, x - nRadius); tail = MIN(x + nRadius + 1, m_nWidth); for(i = head; i < tail; i++) { c = GetPixel(i, y); r += gRed(c); g += gGreen(c); b += gBlue(c); } tail -= head; tmp.SetPixel(x, y, gRGB(r / tail, g / tail, b / tail)); } } for(y = 0; y < m_nHeight; y++) { for(x = 0; x < m_nWidth; x++) { r = 0; g = 0; b = 0; head = MAX(0, y - nRadius); tail = MIN(y + nRadius + 1, m_nHeight); for(i = head; i < tail; i++) { c = tmp.GetPixel(x, i); r += gRed(c); g += gGreen(c); b += gBlue(c); } tail -= head; SetPixel(x, y, gRGB(r / tail, g / tail, b / tail)); } }}void GImage::Sharpen(double dFactor){ GImage imgBlurred; imgBlurred.CopyImage(this); imgBlurred.Blur(dFactor); GImage imgTmp; imgTmp.SetSize(m_nWidth, m_nHeight); GColor col; int nRed, nGreen, nBlue; int x, y; for(y = 0; y < (int)m_nHeight; y++) { for(x = 0; x < (int)m_nWidth; x++) { col = GetPixel(x, y); nRed = 2 * gRed(col); nGreen = 2 * gGreen(col); nBlue = 2 * gBlue(col); col = imgBlurred.GetPixel(x, y); nRed = ClipChan((int)(nRed - gRed(col))); nGreen = ClipChan((int)(nGreen - gGreen(col))); nBlue = ClipChan((int)(nBlue - gBlue(col))); imgTmp.SetPixel(x, y, gRGB(nRed, nGreen, nBlue)); } } SwapData(&imgTmp);}void GImage::Invert(){ int x, y; GColor col; for(y = 0; y < (int)m_nHeight; y++) { for(x = 0; x < (int)m_nWidth; x++) { col = GetPixel(x, y); SetPixel(x, y, gRGB(255 - gRed(col), 255 - gGreen(col), 255 - gBlue(col))); } }}void GImage::InvertRect(GRect* pRect){ int x, y; GColor col; for(y = pRect->y; y < pRect->y + pRect->h; y++) { for(x = pRect->x; x < pRect->x + pRect->w; x++) { col = GetPixel(x, y); SetPixel(x, y, gRGB(255 - gRed(col), 255 - gGreen(col), 255 - gBlue(col))); } }}void GImage::MakeEdgesGlow(float fThresh, int nThickness, int nOpacity, GColor color){ // Make initial mask GImage tmp; tmp.SetSize(m_nWidth, m_nHeight); GColor col, colLeft, colRight, colTop, colBottom; int x, y, dif; for(y = m_nHeight - 2; y > 0; y--) { for(x = m_nWidth - 2; x > 0; x--) { col = GetPixel(x, y); colLeft = GetPixel(x - 1, y); colRight = GetPixel(x + 1, y); colTop = GetPixel(x, y - 1); colBottom = GetPixel(x, y + 1); dif = ABS((int)gRed(col) - (int)gRed(colLeft)) + ABS((int)gGreen(col) - (int)gGreen(colLeft)) + ABS((int)gBlue(col) - (int)gBlue(colLeft)) + ABS((int)gRed(col) - (int)gRed(colRight)) + ABS((int)gGreen(col) - (int)gGreen(colRight)) + ABS((int)gBlue(col) - (int)gBlue(colRight)) + ABS((int)gRed(col) - (int)gRed(colTop)) + ABS((int)gGreen(col) - (int)gGreen(colTop)) + ABS((int)gBlue(col) - (int)gBlue(colTop)) + ABS((int)gRed(col) - (int)gRed(colBottom)) + ABS((int)gGreen(col) - (int)gGreen(colBottom)) + ABS((int)gBlue(col) - (int)gBlue(colBottom)); if((float)dif * gAlpha(col) / 49152 > fThresh) tmp.SetPixel(x, y, nThickness + 1);/* dif = ABS((int)gAlpha(col) - (int)gAlpha(colLeft)) + ABS((int)gAlpha(col) - (int)gAlpha(colRight)) + ABS((int)gAlpha(col) - (int)gAlpha(colTop)) + ABS((int)gAlpha(col) - (int)gAlpha(colBottom)); if((float)dif / 1024 > fThresh) tmp.SetPixel(x, y, nThickness + 1);*/ } } // Make the glowing int n; for(n = nThickness; n >= 0; n--) { for(y = m_nHeight - 2; y > 0; y--) { for(x = m_nWidth - 2; x > 0; x--) { col = tmp.GetPixel(x, y); if(col > (unsigned int)n) { tmp.SetPixel(x - 1, y, tmp.GetPixel(x - 1, y) | n); tmp.SetPixel(x + 1, y, tmp.GetPixel(x + 1, y) | n); tmp.SetPixel(x, y - 1, tmp.GetPixel(x, y - 1) | n); tmp.SetPixel(x, y + 1, tmp.GetPixel(x, y + 1) | n); col = MixColors(color, GetPixel(x, y), nOpacity); SetPixel(x, y, col); } } } }}void GImage::HorizDifferenceize(){ if(m_nWidth <= 1) return; GColor c1, c2; int x, y; for(y = 0; y < m_nHeight; y++) { c1 = GetPixel(0, y); for(x = 1; x < m_nWidth; x++) { c2 = GetPixel(x, y); SetPixel(x, y, gRGB( (256 + gRed(c2) - gRed(c1)) % 256, (256 + gGreen(c2) - gGreen(c1)) % 256, (256 + gBlue(c2) - gBlue(c1)) % 256)); c1 = c2; } }}void GImage::HorizSummize(){ if(m_nWidth <= 1) return; GColor c1, c2; int x, y; for(y = 0; y < m_nHeight; y++) { c1 = GetPixel(0, y); for(x = 1; x < m_nWidth; x++) { c2 = GetPixel(x, y); SetPixel(x, y, gRGB( (256 + gRed(c2) + gRed(c1)) % 256, (256 + gGreen(c2) + gGreen(c1)) % 256, (256 + gBlue(c2) + gBlue(c1)) % 256)); c1 = c2; } }}void GImage::Draw3DLine(const struct Point3D* pA, const struct Point3D* pB, struct Transform* pCamera, GColor color){ struct Point3D a = *pA; struct Point3D b = *pB; a.Transform(pCamera); b.Transform(pCamera); SafeDrawLine((int)a.m_vals[0], (int)a.m_vals[1], (int)b.m_vals[0], (int)b.m_vals[1], color);}void GImage::DrawBezier(GBezier* pCurve, GColor color, double dStart, double dEnd, double dStep, struct Transform* pCamera){ Transform t; Point3D prev; Point3D point; pCurve->GetPoint(dStart, &prev); point.Transform(pCamera); while(true) { dStart += dStep; if(dStart > dEnd) break; pCurve->GetPoint(dStart, &point); Draw3DLine(&point, &prev, pCamera, color); prev = point; }}int GImage::MeasureHardTextWidth(int height, const char* szText, float width){ bool bBig = (height > 24); int sx, sy, sw, sh; int x = 0; int nCharWidth; while(true) { char c = *szText; if(c == '\0') break; if(bBig) { GHardFont_GetCharCoords(c, &sx, &sy, &sw, &sh); nCharWidth = (int)(sw * height * width) / sh; } else { GSmallHardFont_GetCharCoords(c, &sx, &sy, &sw, &sh); nCharWidth = sw; } x += nCharWidth; szText++; } return x;}int GImage::CountHardTextChars(int horizArea, int height, const char* szText, float width){ bool bBig = (height > 24); int sx, sy, sw, sh; int x = 0; int nCharWidth; int nChars = 0; while(true) { char c = *szText; if(c == '\0') break; if(bBig) { GHardFont_GetCharCoords(c, &sx, &sy, &sw, &sh); nCharWidth = (int)(sw * height * width) / sh; } else { GSmallHardFont_GetCharCoords(c, &sx, &sy, &sw, &sh); nCharWidth = sw; } x += nCharWidth; szText++; if(x > horizArea) break; nChars++; } return nChars;}void GImage::DrawHardText(GRect* pRect, const char* szText, GColor col, float width){ bool bBig = (pRect->h > 24); int sx, sy, sw, sh; int x = 0; while(true) { char c = *szText; if(c == '\0') break; if(bBig) GHardFont_GetCharCoords(c, &sx, &sy, &sw, &sh); else { GSmallHardFont_GetCharCoords(c, &sx, &sy, &sw, &sh); GAssert(sh <= 24, "problem with big threshold"); } GAssert(pRect->x >= 0, "todo: this case not handled yet"); int yStart = 0; if(pRect->y < 0) yStart = -pRect->y; if(bBig) { int h = pRect->h; if(pRect->y + h > m_nHeight) h = m_nHeight - pRect->y; int nCharWidth = (int)(sw * pRect->h * width) / sh; int n; for(n = 0; n < nCharWidth; n++) { if(x >= pRect->w) break; int y; for(y = yStart; y < h; y++) SetPixel(pRect->x + x, pRect->y + y, GHardFont_GetAlphaBlended(sx + n * sw / nCharWidth, sy + y * sh / pRect->h, col, GetPixel(pRect->x + x, pRect->y + y))); x++; } } else { if(pRect->y + sh > m_nHeight) sh = m_nHeight - pRect->y; int n; for(n = 0; n < sw; n++) { if(x >= pRect->w) break; int y; for(y = yStart; y < sh; y++) SetPixel(pRect->x + x, pRect->y + y, GSmallHardFont_GetAlphaBlended(sx + n, sy + y, col, GetPixel(pRect->x + x, pRect->y + y))); x++; } } szText++; }}void GImage::Blit(int x, int y, GImage* pSource, GRect* pSourceRect){ int sx = pSourceRect->x; int sy = pSourceRect->y; int sw = pSourceRect->w; int sh = pSourceRect->h; if(x < 0) { sx -= x; sw += x; x = 0; } if(x + sw > m_nWidth) sw = m_nWidth - x; if(y < 0) { sy -= y; sh += y; y = 0; } if(y + sh > m_nHeight) sh = m_nHeight - y; int dst = y * m_nWidth + x; int src = sy * pSource->m_nWidth + sx; sw *= sizeof(GColor); for( ; sh > 0; sh--) { memcpy(&m_pPixels[dst], &pSource->m_pPixels[src], sw); dst += m_nWidth; src += pSource->m_nWidth; }}void GImage::AlphaBlit(int x, int y, GImage* pSource, GRect* pSourceRect){ int sx = pSourceRect->x; int sy = pSourceRect->y; int sw = pSourceRect->w; int sh = pSourceRect->h; if(x < 0) { sx -= x; sw += x; x = 0; } if(x + sw > m_nWidth) sw = m_nWidth - x; if(y < 0) { sy -= y; sh += y; y = 0; } if(y + sh > m_nHeight) sh = m_nHeight - y; int dst = y * m_nWidth + x; int src = sy * pSource->m_nWidth + sx; int xx, a; GColor pix, pixOld; for( ; sh > 0; sh--) { for(xx = 0; xx < sw; xx++) { pix = pSource->m_pPixels[src + xx]; a = gAlpha(pix);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -