📄 ximatran.cpp
字号:
{
if (!pDib) return false;
if (head.biBitCount<=8){
if (IsGrayScale()){ //GRAYSCALE, selection
if (pSelection){
for(long y=info.rSelectionBox.bottom; y<info.rSelectionBox.top; y++){
for(long x=info.rSelectionBox.left; x<info.rSelectionBox.right; x++){
#if CXIMAGE_SUPPORT_SELECTION
if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
{
SetPixelIndex(x,y,(BYTE)(255-GetPixelIndex(x,y)));
}
}
}
} else {
for(long y=0; y<head.biHeight; y++){
for(long x=0; x<head.biWidth; x++){
SetPixelIndex(x,y,(BYTE)(255-GetPixelIndex(x,y)));
}
}
}
} else { //PALETTE, full image
RGBQUAD* ppal=GetPalette();
for(DWORD i=0;i<head.biClrUsed;i++){
ppal[i].rgbBlue =(BYTE)(255-ppal[i].rgbBlue);
ppal[i].rgbGreen =(BYTE)(255-ppal[i].rgbGreen);
ppal[i].rgbRed =(BYTE)(255-ppal[i].rgbRed);
}
}
} else {
if (pSelection==NULL){ //RGB, full image
BYTE *iSrc=info.pImage;
for(unsigned long i=0; i < head.biSizeImage ; i++){
*iSrc=(BYTE)~(*(iSrc));
iSrc++;
}
} else { // RGB with selection
RGBQUAD color;
for(long y=info.rSelectionBox.bottom; y<info.rSelectionBox.top; y++){
for(long x=info.rSelectionBox.left; x<info.rSelectionBox.right; x++){
#if CXIMAGE_SUPPORT_SELECTION
if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
{
color = GetPixelColor(x,y);
color.rgbRed = (BYTE)(255-color.rgbRed);
color.rgbGreen = (BYTE)(255-color.rgbGreen);
color.rgbBlue = (BYTE)(255-color.rgbBlue);
SetPixelColor(x,y,color);
}
}
}
}
//<DP> invert transparent color too
info.nBkgndColor.rgbBlue = (BYTE)(255-info.nBkgndColor.rgbBlue);
info.nBkgndColor.rgbGreen = (BYTE)(255-info.nBkgndColor.rgbGreen);
info.nBkgndColor.rgbRed = (BYTE)(255-info.nBkgndColor.rgbRed);
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
#endif //CXIMAGE_SUPPORT_BASICTRANSFORMATIONS
////////////////////////////////////////////////////////////////////////////////
#if CXIMAGE_SUPPORT_TRANSFORMATION
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool CxImage::Rotate(float angle, CxImage* iDst)
{
if (!pDib) return false;
// $Id: FilterRotate.cpp,v 1.10 2000/12/18 22:42:53 uzadow Exp $
// Copyright (c) 1996-1998 Ulrich von Zadow
// Negative the angle, because the y-axis is negative.
double ang = -angle*acos((float)0)/90;
int newWidth, newHeight;
int nWidth = GetWidth();
int nHeight= GetHeight();
double cos_angle = cos(ang);
double sin_angle = sin(ang);
// Calculate the size of the new bitmap
POINT p1={0,0};
POINT p2={nWidth,0};
POINT p3={0,nHeight};
POINT p4={nWidth-1,nHeight};
POINT newP1,newP2,newP3,newP4, leftTop, rightTop, leftBottom, rightBottom;
newP1.x = p1.x;
newP1.y = p1.y;
newP2.x = (long)(p2.x*cos_angle - p2.y*sin_angle);
newP2.y = (long)(p2.x*sin_angle + p2.y*cos_angle);
newP3.x = (long)(p3.x*cos_angle - p3.y*sin_angle);
newP3.y = (long)(p3.x*sin_angle + p3.y*cos_angle);
newP4.x = (long)(p4.x*cos_angle - p4.y*sin_angle);
newP4.y = (long)(p4.x*sin_angle + p4.y*cos_angle);
leftTop.x = min(min(newP1.x,newP2.x),min(newP3.x,newP4.x));
leftTop.y = min(min(newP1.y,newP2.y),min(newP3.y,newP4.y));
rightBottom.x = max(max(newP1.x,newP2.x),max(newP3.x,newP4.x));
rightBottom.y = max(max(newP1.y,newP2.y),max(newP3.y,newP4.y));
leftBottom.x = leftTop.x;
leftBottom.y = rightBottom.y;
rightTop.x = rightBottom.x;
rightTop.y = leftTop.y;
newWidth = rightTop.x - leftTop.x;
newHeight= leftBottom.y - leftTop.y;
CxImage imgDest;
imgDest.CopyInfo(*this);
imgDest.Create(newWidth,newHeight,GetBpp(),GetType());
imgDest.SetPalette(GetPalette());
#if CXIMAGE_SUPPORT_ALPHA
if(AlphaIsValid()) //MTA: Fix for rotation problem when the image has an alpha channel
{
imgDest.AlphaCreate();
imgDest.AlphaClear();
}
#endif //CXIMAGE_SUPPORT_ALPHA
int x,y,newX,newY,oldX,oldY;
if (head.biClrUsed==0){ //RGB
for (y = leftTop.y, newY = 0; y<=leftBottom.y; y++,newY++){
info.nProgress = (long)(100*newY/newHeight);
if (info.nEscape) break;
for (x = leftTop.x, newX = 0; x<=rightTop.x; x++,newX++){
oldX = (long)(x*cos_angle + y*sin_angle - 0.5);
oldY = (long)(y*cos_angle - x*sin_angle - 0.5);
imgDest.SetPixelColor(newX,newY,GetPixelColor(oldX,oldY));
#if CXIMAGE_SUPPORT_ALPHA
imgDest.AlphaSet(newX,newY,AlphaGet(oldX,oldY)); //MTA: copy the alpha value
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
} else { //PALETTE
for (y = leftTop.y, newY = 0; y<=leftBottom.y; y++,newY++){
info.nProgress = (long)(100*newY/newHeight);
if (info.nEscape) break;
for (x = leftTop.x, newX = 0; x<=rightTop.x; x++,newX++){
oldX = (long)(x*cos_angle + y*sin_angle - 0.5);
oldY = (long)(y*cos_angle - x*sin_angle - 0.5);
imgDest.SetPixelIndex(newX,newY,GetPixelIndex(oldX,oldY));
#if CXIMAGE_SUPPORT_ALPHA
imgDest.AlphaSet(newX,newY,AlphaGet(oldX,oldY)); //MTA: copy the alpha value
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
}
//select the destination
if (iDst) iDst->Transfer(imgDest);
else Transfer(imgDest);
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::Rotate180(CxImage* iDst)
{
if (!pDib) return false;
long wid = GetWidth();
long ht = GetHeight();
CxImage imgDest;
imgDest.CopyInfo(*this);
imgDest.Create(wid,ht,GetBpp(),GetType());
imgDest.SetPalette(GetPalette());
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid()) imgDest.AlphaCreate();
#endif //CXIMAGE_SUPPORT_ALPHA
long x,y,y2;
for (y = 0; y < ht; y++){
info.nProgress = (long)(100*y/ht); //<Anatoly Ivasyuk>
y2=ht-y-1;
for (x = 0; x < wid; x++){
if(head.biClrUsed==0)//RGB
imgDest.SetPixelColor(wid-x-1, y2, GetPixelColor(x, y));
else //PALETTE
imgDest.SetPixelIndex(wid-x-1, y2, GetPixelIndex(x, y));
#if CXIMAGE_SUPPORT_ALPHA
if (AlphaIsValid()) imgDest.AlphaSet(wid-x-1, y2,AlphaGet(x, y));
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
//select the destination
if (iDst) iDst->Transfer(imgDest);
else Transfer(imgDest);
return true;
}
////////////////////////////////////////////////////////////////////////////////
bool CxImage::Resample(long newx, long newy, int mode, CxImage* iDst)
{
if (newx==0 || newy==0) return false;
if (head.biWidth==newx && head.biHeight==newy){
if (iDst) iDst->Copy(*this);
return true;
}
float xScale, yScale, fX, fY;
xScale = (float)head.biWidth / (float)newx;
yScale = (float)head.biHeight / (float)newy;
CxImage newImage;
newImage.CopyInfo(*this);
newImage.Create(newx,newy,head.biBitCount,GetType());
newImage.SetPalette(GetPalette());
if (!newImage.IsValid()) return false;
if (head.biWidth==newx && head.biHeight==newy){
Transfer(newImage);
return true;
}
switch (mode) {
case 1: // nearest pixel
{
for(long y=0; y<newy; y++){
info.nProgress = (long)(100*y/newy);
if (info.nEscape) break;
fY = y * yScale;
for(long x=0; x<newx; x++){
fX = x * xScale;
newImage.SetPixelColor(x,y,GetPixelColor((long)fX,(long)fY));
}
}
break;
}
case 2: // bicubic interpolation by Blake L. Carlson <blake-carlson(at)uiowa(dot)edu
{
float f_x, f_y, a, b, rr, gg, bb, r1, r2;
int i_x, i_y, xx, yy;
RGBQUAD rgb;
for(long y=0; y<newy; y++){
info.nProgress = (long)(100*y/newy);
if (info.nEscape) break;
f_y = (float) y * yScale;
i_y = (int) floor(f_y);
a = f_y - (float)floor(f_y);
for(long x=0; x<newx; x++){
f_x = (float) x * xScale;
i_x = (int) floor(f_x);
b = f_x - (float)floor(f_x);
rr = gg = bb = 0.0F;
for(int m=-1; m<3; m++) {
r1 = b3spline((float) m - a);
for(int n=-1; n<3; n++) {
r2 = b3spline(-1.0F*((float)n - b));
xx = i_x+n+2;
yy = i_y+m+2;
if (xx<0) xx=0;
if (yy<0) yy=0;
if (xx>=head.biWidth) xx=head.biWidth-1;
if (yy>=head.biHeight) yy=head.biHeight-1;
rgb = GetPixelColor(xx,yy);
rr += rgb.rgbRed * r1 * r2;
gg += rgb.rgbGreen * r1 * r2;
bb += rgb.rgbBlue * r1 * r2;
}
}
newImage.SetPixelColor(x,y,RGB(rr,gg,bb));
}
}
break;
}
default: // bilinear interpolation
if (!(head.biWidth>newx && head.biHeight>newy && head.biBitCount==24)) {
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -