📄 image.cpp
字号:
dest_pixel[0] = src_pixel[0];
dest_pixel[1] = src_pixel[1];
dest_pixel[2] = src_pixel[2];
dest_pixel += 3;
if ( source_alpha )
*(target_alpha++) = *src_alpha_pixel ;
x += x_delta;
}
y += y_delta;
}
// In case this is a cursor, make sure the hotspot is scalled accordingly:
if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) )
image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,
(GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X)*width)/old_width);
if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y) )
image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y,
(GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y)*height)/old_height);
return image;
}
wxImage wxImage::Rotate90( bool clockwise ) const
{
wxImage image;
wxCHECK_MSG( Ok(), image, wxT("invalid image") );
image.Create( M_IMGDATA->m_height, M_IMGDATA->m_width, false );
unsigned char *data = image.GetData();
wxCHECK_MSG( data, image, wxT("unable to create image") );
unsigned char *source_data = M_IMGDATA->m_data;
unsigned char *target_data;
unsigned char *alpha_data = 0 ;
unsigned char *source_alpha = 0 ;
unsigned char *target_alpha = 0 ;
if (M_IMGDATA->m_hasMask)
{
image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
}
else
{
source_alpha = M_IMGDATA->m_alpha ;
if ( source_alpha )
{
image.SetAlpha() ;
alpha_data = image.GetAlpha() ;
}
}
long height = M_IMGDATA->m_height;
long width = M_IMGDATA->m_width;
for (long j = 0; j < height; j++)
{
for (long i = 0; i < width; i++)
{
if (clockwise)
{
target_data = data + (((i+1)*height) - j - 1)*3;
if(source_alpha)
target_alpha = alpha_data + (((i+1)*height) - j - 1);
}
else
{
target_data = data + ((height*(width-1)) + j - (i*height))*3;
if(source_alpha)
target_alpha = alpha_data + ((height*(width-1)) + j - (i*height));
}
memcpy( target_data, source_data, 3 );
source_data += 3;
if(source_alpha)
{
memcpy( target_alpha, source_alpha, 1 );
source_alpha += 1;
}
}
}
return image;
}
wxImage wxImage::Mirror( bool horizontally ) const
{
wxImage image;
wxCHECK_MSG( Ok(), image, wxT("invalid image") );
image.Create( M_IMGDATA->m_width, M_IMGDATA->m_height, false );
unsigned char *data = image.GetData();
wxCHECK_MSG( data, image, wxT("unable to create image") );
if (M_IMGDATA->m_hasMask)
image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
long height = M_IMGDATA->m_height;
long width = M_IMGDATA->m_width;
unsigned char *source_data = M_IMGDATA->m_data;
unsigned char *target_data;
if (horizontally)
{
for (long j = 0; j < height; j++)
{
data += width*3;
target_data = data-3;
for (long i = 0; i < width; i++)
{
memcpy( target_data, source_data, 3 );
source_data += 3;
target_data -= 3;
}
}
}
else
{
for (long i = 0; i < height; i++)
{
target_data = data + 3*width*(height-1-i);
memcpy( target_data, source_data, (size_t)3*width );
source_data += 3*width;
}
}
return image;
}
wxImage wxImage::GetSubImage( const wxRect &rect ) const
{
wxImage image;
wxCHECK_MSG( Ok(), image, wxT("invalid image") );
wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) && (rect.GetRight()<=GetWidth()) && (rect.GetBottom()<=GetHeight()),
image, wxT("invalid subimage size") );
int subwidth=rect.GetWidth();
const int subheight=rect.GetHeight();
image.Create( subwidth, subheight, false );
unsigned char *subdata = image.GetData(), *data=GetData();
wxCHECK_MSG( subdata, image, wxT("unable to create image") );
if (M_IMGDATA->m_hasMask)
image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
const int subleft=3*rect.GetLeft();
const int width=3*GetWidth();
subwidth*=3;
data+=rect.GetTop()*width+subleft;
for (long j = 0; j < subheight; ++j)
{
memcpy( subdata, data, subwidth);
subdata+=subwidth;
data+=width;
}
return image;
}
wxImage wxImage::Size( const wxSize& size, const wxPoint& pos,
int r_, int g_, int b_ ) const
{
wxImage image;
wxCHECK_MSG( Ok(), image, wxT("invalid image") );
wxCHECK_MSG( (size.GetWidth() > 0) && (size.GetHeight() > 0), image, wxT("invalid size") );
int width = GetWidth(), height = GetHeight();
image.Create(size.GetWidth(), size.GetHeight(), false);
unsigned char r = (unsigned char)r_;
unsigned char g = (unsigned char)g_;
unsigned char b = (unsigned char)b_;
if ((r_ == -1) && (g_ == -1) && (b_ == -1))
{
GetOrFindMaskColour( &r, &g, &b );
image.SetMaskColour(r, g, b);
}
image.SetRGB(wxRect(), r, g, b);
wxRect subRect(pos.x, pos.y, width, height);
wxRect finalRect(0, 0, size.GetWidth(), size.GetHeight());
subRect.Intersect(finalRect);
if (!subRect.IsEmpty())
{
if ((subRect.GetWidth() == width) && (subRect.GetHeight() == height))
image.Paste(*this, pos.x, pos.y);
else
image.Paste(GetSubImage(subRect), pos.x, pos.y);
}
return image;
}
void wxImage::Paste( const wxImage &image, int x, int y )
{
wxCHECK_RET( Ok(), wxT("invalid image") );
wxCHECK_RET( image.Ok(), wxT("invalid image") );
int xx = 0;
int yy = 0;
int width = image.GetWidth();
int height = image.GetHeight();
if (x < 0)
{
xx = -x;
width += x;
}
if (y < 0)
{
yy = -y;
height += y;
}
if ((x+xx)+width > M_IMGDATA->m_width)
width = M_IMGDATA->m_width - (x+xx);
if ((y+yy)+height > M_IMGDATA->m_height)
height = M_IMGDATA->m_height - (y+yy);
if (width < 1) return;
if (height < 1) return;
if ((!HasMask() && !image.HasMask()) ||
(HasMask() && !image.HasMask()) ||
((HasMask() && image.HasMask() &&
(GetMaskRed()==image.GetMaskRed()) &&
(GetMaskGreen()==image.GetMaskGreen()) &&
(GetMaskBlue()==image.GetMaskBlue()))))
{
width *= 3;
unsigned char* source_data = image.GetData() + xx*3 + yy*3*image.GetWidth();
int source_step = image.GetWidth()*3;
unsigned char* target_data = GetData() + (x+xx)*3 + (y+yy)*3*M_IMGDATA->m_width;
int target_step = M_IMGDATA->m_width*3;
for (int j = 0; j < height; j++)
{
memcpy( target_data, source_data, width );
source_data += source_step;
target_data += target_step;
}
return;
}
if (!HasMask() && image.HasMask())
{
unsigned char r = image.GetMaskRed();
unsigned char g = image.GetMaskGreen();
unsigned char b = image.GetMaskBlue();
width *= 3;
unsigned char* source_data = image.GetData() + xx*3 + yy*3*image.GetWidth();
int source_step = image.GetWidth()*3;
unsigned char* target_data = GetData() + (x+xx)*3 + (y+yy)*3*M_IMGDATA->m_width;
int target_step = M_IMGDATA->m_width*3;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i+=3)
{
if ((source_data[i] != r) &&
(source_data[i+1] != g) &&
(source_data[i+2] != b))
{
memcpy( target_data+i, source_data+i, 3 );
}
}
source_data += source_step;
target_data += target_step;
}
}
}
void wxImage::Replace( unsigned char r1, unsigned char g1, unsigned char b1,
unsigned char r2, unsigned char g2, unsigned char b2 )
{
wxCHECK_RET( Ok(), wxT("invalid image") );
unsigned char *data = GetData();
const int w = GetWidth();
const int h = GetHeight();
for (int j = 0; j < h; j++)
for (int i = 0; i < w; i++)
{
if ((data[0] == r1) && (data[1] == g1) && (data[2] == b1))
{
data[0] = r2;
data[1] = g2;
data[2] = b2;
}
data += 3;
}
}
wxImage wxImage::ConvertToMono( unsigned char r, unsigned char g, unsigned char b ) const
{
wxImage image;
wxCHECK_MSG( Ok(), image, wxT("invalid image") );
image.Create( M_IMGDATA->m_width, M_IMGDATA->m_height, false );
unsigned char *data = image.GetData();
wxCHECK_MSG( data, image, wxT("unable to create image") );
if (M_IMGDATA->m_hasMask)
{
if (M_IMGDATA->m_maskRed == r && M_IMGDATA->m_maskGreen == g &&
M_IMGDATA->m_maskBlue == b)
image.SetMaskColour( 255, 255, 255 );
else
image.SetMaskColour( 0, 0, 0 );
}
long size = M_IMGDATA->m_height * M_IMGDATA->m_width;
unsigned char *srcd = M_IMGDATA->m_data;
unsigned char *tard = image.GetData();
for ( long i = 0; i < size; i++, srcd += 3, tard += 3 )
{
if (srcd[0] == r && srcd[1] == g && srcd[2] == b)
tard[0] = tard[1] = tard[2] = 255;
else
tard[0] = tard[1] = tard[2] = 0;
}
return image;
}
int wxImage::GetWidth() const
{
wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
return M_IMGDATA->m_width;
}
int wxImage::GetHeight() const
{
wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
return M_IMGDATA->m_height;
}
long wxImage::XYToIndex(int x, int y) const
{
if ( Ok() &&
x >= 0 && y >= 0 &&
x < M_IMGDATA->m_width && y < M_IMGDATA->m_height )
{
return y*M_IMGDATA->m_width + x;
}
return -1;
}
void wxImage::SetRGB( int x, int y, unsigned char r, unsigned char g, unsigned char b )
{
long pos = XYToIndex(x, y);
wxCHECK_RET( pos != -1, wxT("invalid image coordinates") );
pos *= 3;
M_IMGDATA->m_data[ pos ] = r;
M_IMGDATA->m_data[ pos+1 ] = g;
M_IMGDATA->m_data[ pos+2 ] = b;
}
void wxImage::SetRGB( const wxRect& rect_, unsigned char r, unsigned char g, unsigned char b )
{
wxCHECK_RET( Ok(), wxT("invalid image") );
wxRect rect(rect_);
wxRect imageRect(0, 0, GetWidth(), GetHeight());
if ( rect == wxRect() )
{
rect = imageRect;
}
else
{
wxCHECK_RET( imageRect.Inside(rect.GetTopLeft()) &&
imageRect.Inside(rect.GetBottomRight()),
wxT("invalid bounding rectangle") );
}
int x1 = rect.GetLeft(),
y1 = rect.GetTop(),
x2 = rect.GetRight() + 1,
y2 = rect.GetBottom() + 1;
unsigned char *data wxDUMMY_INITIALIZE(NULL);
int x, y, width = GetWidth();
for (y = y1; y < y2; y++)
{
data = M_IMGDATA->m_data + (y*width + x1)*3;
for (x = x1; x < x2; x++)
{
*data++ = r;
*data++ = g;
*data++ = b;
}
}
}
unsigned char wxImage::GetRed( int x, int y ) const
{
long pos = XYToIndex(x, y);
wxCHECK_MSG( pos != -1, 0, wxT("invalid image coordinates") );
pos *= 3;
return M_IMGDATA->m_data[pos];
}
unsigned char wxImage::GetGreen( int x, int y ) const
{
long pos = XYToIndex(x, y);
wxCHECK_MSG( pos != -1, 0, wxT("invalid image coordinates") );
pos *= 3;
return M_IMGDATA->m_data[pos+1];
}
unsigned char wxImage::GetBlue( int x, int y ) const
{
long pos = XYToIndex(x, y);
wxCHECK_MSG( pos != -1, 0, wxT("invalid image coordinates") );
pos *= 3;
return M_IMGDATA->m_data[pos+2];
}
bool wxImage::Ok() const
{
// image of 0 width or height can't be considered ok - at least because it
// causes crashes in ConvertToBitmap() if we don't catch it in time
wxImageRefData *data = M_IMGDATA;
return data && data->m_ok && data->m_width && data->m_height;
}
unsigned char *wxImage::GetData() const
{
wxCHECK_MSG( Ok(), (unsigned char *)NULL, wxT("invalid image") );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -