📄 image.cc
字号:
d->i+=value; OP_END}/** Clip all pixel values above maxValue to maxValue @param maxValue maximum value in image*/void Image::clipMax(int maxValue) { OP_BEGIN d->i.min(maxValue); OP_END}/** Clip all pixel values below minValue to minValue @param minValue minimum value in image*/void Image::clipMin(int minValue) { OP_BEGIN d->i.max(minValue); OP_END}/** Replace each image pixel by its square root.*/void Image::sqrt() { OP_BEGIN d->i.sqrt(); OP_END}/** Linear normalization of the pixel values between a and b. @param a lower value @param b upper value*/void Image::normalize(int a,int b) { OP_BEGIN d->i.normalize(a,b); OP_END}/** Quantize pixel values into levels. @param n Number of levels*/void Image::quantize(const unsigned int n/*=256*/) { OP_BEGIN d->i.quantize(n); OP_END}/** Flip image by specified axis @param axis Axis for flipping. Can be 'x', 'y', 'z' or 'v'*/void Image::flip(char axis) { OP_BEGIN d->i.mirror(axis); OP_END}/** Convert image to greyscale*/void Image::toGrey() { OP_BEGIN grayscale(d->i); OP_END}/** Equalize histogram*/void Image::equalizeHistogram() { OP_BEGIN d->i.equalize_histogram(); OP_END}/** add noise to image @param sigma power of the noise. if sigma<0, it corresponds to the percentage of the maximum image value. @param ntype noise type. can be 0=gaussian, 1=uniform or 2=Salt and Pepper.*/void Image::noise(double sigma/*=-20*/,int ntype/*=0*/) { OP_BEGIN d->i.noise(sigma,ntype); OP_END}/** Apply a median filter. @param n size of filter*/void Image::median(int n/*=3*/) { OP_BEGIN d->i.blur_median(n); OP_END}/** Apply a deriche filter on the image. The Canny-Deriche filter is a recursive algorithm allowing to compute blurred derivatives of order 0,1 or 2 of an image.*/void Image::deriche(float sigma/*=1*/,int order/*=0*/,char axe/*='x'*/,unsigned int cond/*=1*/) { OP_BEGIN d->i.deriche(sigma,order,axe,cond); OP_END}/** Blur the image with an anisotropic exponential filter (Deriche filter of order 0).*/void Image::blur(float sigmax,float sigmay,float sigmaz,unsigned int cond/*=1*/) { OP_BEGIN d->i.blur(sigmax,sigmay,sigmaz,cond); OP_END}/** Blur the image with a Canny-Deriche filter.*/void Image::blur(float sigma,unsigned int cond/*=1*/) { OP_BEGIN d->i.blur(sigma,cond); OP_END}/** Blur an image following in an anistropic way. @param amplitude amplitude of the anisotropic blur. @param sharpness define the contour preservation. @param anisotropy define the smoothing anisotropy. @param alpha image pre-blurring (gaussian). @param sigma regularity of the tensor-valued geometry. @param dl spatial discretization. @param da angular discretization. @param gauss_prec precision of the gaussian function. @param interpolation Used interpolation scheme (0 = nearest-neighbor, 1 = linear, 2 = Runge-Kutta) @param fast_approx Tell to use the fast approximation or not*/void Image::blur_anisotropic(float amplitude,float sharpness/*=0.7f*/,float anisotropy/*=0.3f*/,float alpha/*=0.6f*/,float sigma/*=1.1f*/,float dl/*=0.8f*/,float da/*=30.0f*/,float gauss_prec/*=2.0f*/,unsigned int interpolation/*=0*/,bool fast_approx/*=true*/,float geom_factor/*=1.0f*/) { OP_BEGIN d->i.blur_anisotropic(amplitude,sharpness,anisotropy,alpha,sigma,dl,da,gauss_prec,interpolation,fast_approx,geom_factor); OP_END}/** Sharpen image using anisotropic shock filters.*/void Image::sharpen(float amplitude/*=50.0f*/,float edge/*=1.0f*/,float alpha/*=0.0f*/,float sigma/*=0.0f*/) { OP_BEGIN d->i.sharpen(amplitude,edge,alpha,sigma); OP_END}/** Sharpen image using anisotropic shock filters. @param nChannels new number of channels*/void Image::convertChannels(int nChannels) { OP_BEGIN convert_channels(d->i,nChannels); OP_END}/** Copy portion of RGB image defined by corner x0,y0 and dimensions wx,wy to target ARGB buffer @param x0 X coordinate of subsection origin in image @param y0 Y coordinate of subsection origin in image @param wx Width of image subsection @param wy Height of image subsection @param pixdata Buffer that will recive the pixel data. Must be at least wx*wy*sizeof(int) large*/void Image::imgToRGB(int *pixdata,int x0,int y0,int wx,int wy) { Pixel *r,*g,*b; ARGB<Pixel> pixel; pixel.a=0xff; for (int y=y0;y<y0+wy;y++) { r=d->i.ptr(x0,y,0,0); g=d->i.ptr(x0,y,0,1); b=d->i.ptr(x0,y,0,2); for (int x=0;x<wx;x++) { pixel.r=*r;r++; pixel.g=*g;g++; pixel.b=*b;b++; *pixdata=pixel.argb; pixdata++; } }}/** Copy portion of RGBA image defined by corner x0,y0 and dimensions wx,wy to target ARGB buffer @param x0 X coordinate of subsection origin in image @param y0 Y coordinate of subsection origin in image @param wx Width of image subsection @param wy Height of image subsection @param pixdata Buffer that will recive the pixel data. Must be at least wx*wy*sizeof(int) large*/void Image::imgToRGBA(int *pixdata,int x0,int y0,int wx,int wy) { Pixel *r,*g,*b,*a; ARGB<Pixel> pixel; for (int y=y0;y<y0+wy;y++) { r=d->i.ptr(x0,y,0,0); g=d->i.ptr(x0,y,0,1); b=d->i.ptr(x0,y,0,2); a=d->i.ptr(x0,y,0,3); for (int x=0;x<wx;x++) { pixel.r=*r;r++; pixel.g=*g;g++; pixel.b=*b;b++; pixel.a=*a;a++; *pixdata=pixel.argb; pixdata++; } }}/** Copy portion of greyscale image defined by corner x0,y0 and dimensions wx,wy to target ARGB buffer @param x0 X coordinate of subsection origin in image @param y0 Y coordinate of subsection origin in image @param wx Width of image subsection @param wy Height of image subsection @param pixdata Buffer that will recive the pixel data. Must be at least wx*wy*sizeof(int) large*/void Image::imgGreyToRGB(int *pixdata,int x0,int y0,int wx,int wy) { Pixel *l; ARGB<Pixel> pixel; pixel.a=0xff; for (int y=y0;y<y0+wy;y++) { l=d->i.ptr(x0,y,0,0); for (int x=0;x<wx;x++) { pixel.b=pixel.g=pixel.r=*l;l++; *pixdata=pixel.argb; pixdata++; } }}/** Copy portion of greyscale+alpha image defined by corner x0,y0 and dimensions wx,wy to target ARGB buffer @param x0 X coordinate of subsection origin in image @param y0 Y coordinate of subsection origin in image @param wx Width of image subsection @param wy Height of image subsection @param pixdata Buffer that will recive the pixel data. Must be at least wx*wy*sizeof(int) large*/void Image::imgGreyToRGBA(int *pixdata,int x0,int y0,int wx,int wy) { Pixel *l,*a; ARGB<Pixel> pixel; for (int y=y0;y<y0+wy;y++) { l=d->i.ptr(x0,y,0,0); a=d->i.ptr(x0,y,0,1); for (int x=0;x<wx;x++) { pixel.b=pixel.g=pixel.r=*l;l++; pixel.a=*a;a++; *pixdata=pixel.argb; pixdata++; } }}/** return image data as QImage*/QImage Image::toQImage() { int c=d->i.dimv(); int wx=d->i.dimx(); int wy=d->i.dimy(); if (c>=4) { //RGBA QImage img(wx,wy,QImage::Format_ARGB32); imgToRGBA((int*)img.bits(),0,0,wx,wy); return img; } else if (c==3) { //RGB QImage img(wx,wy,QImage::Format_RGB32); imgToRGB((int*)img.bits(),0,0,wx,wy); return img; } else if (c==2) { //Greyscale with alpha QImage img(wx,wy,QImage::Format_ARGB32); imgGreyToRGBA((int*)img.bits(),0,0,wx,wy); return img; } else if (c==1) { //Greyscale QImage img(wx,wy,QImage::Format_RGB32); imgGreyToRGB((int*)img.bits(),0,0,wx,wy); return img; } return QImage(); //Invalid image}/** Draw image using QPainter @param p painter used to draw image @param source source rectangle - which part of image to draw @param target destination rectangle - which area to draw to @param subsource subpixel-accurate subset of source*/void Image::draw(QPainter *p,const QRect &source,const QRect &target,const QRectF &subsource/*=QRectF()*/) { int wx=source.width(); int wy=source.height(); int x0=source.left(); int y0=source.top(); QRect source0(0,0,wx,wy); int bytes=wx*wy*4;//RGBA if (d->pix_w!=wx || d->pix_h!=wy) { //Size was changed since last time free(d->pixdata); d->pixdata=NULL; } if (!d->pixdata) { d->pixdata=(int *)malloc(bytes); d->pix_x=x0; d->pix_y=y0; d->pix_w=wx; d->pix_h=wy; } assert(sizeof(ARGB<Pixel>)==sizeof(int)); int c=d->i.dimv(); if (c<=0) return; //Invalid image if (c>=3) { //RGB,RGBA, or even more channels (anything over RGBA is ignored :) imgToRGB(d->pixdata,x0,y0,wx,wy); } else if (c==1 || c==2) { //Greyscale. 2=greyscale with alpha imgGreyToRGB(d->pixdata,x0,y0,wx,wy); } QImage *q=new QImage((uchar *)d->pixdata,wx,wy,QImage::Format_RGB32); if (subsource.isEmpty()) { p->drawImage(target,*q,source0); } else { QRectF subsource0(frac(subsource.left()),frac(subsource.top()),subsource.width(),subsource.height()); p->drawImage(target,*q,subsource0); } delete q;}/** Return width of the image*/int Image::x() const { return d->i.dimx();}/** Return number of channels in image*/int Image::channels() const { return d->i.dimv();}/** Return filename of the image - filename that was used when loading the image or under which was the image last saved*/QString Image::name() const { return d->imgName;}/** Return basename of the image (filename with any path stripped) - filename that was used when loading the image or under which was the image last saved*/QString Image::baseName() const { return d->imgName.replace(QRegExp("^.*/"),"");}/** Same as \see name, but return absolute filename.*/QString Image::absoluteName() const { return d->imgFullName;}/** Return map with image information*/SMap Image::info() const { SMap r; r[QObject::tr("X (width)")]=QString::number(x()); r[QObject::tr("Y (height)")]=QString::number(y()); r[QObject::tr("Pixels")]=QString::number(x()*y()); r[QObject::tr("Channels")]=QString::number(d->i.dimv()); r[QObject::tr("Name")]=d->imgName; r[QObject::tr("Name (abs.)")]=d->imgFullName; r[QObject::tr("Pixel type")]=QString(d->i.pixel_type()); return r;}/** Return height of the image*/int Image::y() const { return d->i.dimy();}/** copy image to clipboard*/void Image::copy() { OP_BEGIN QClipboard *clip=QApplication::clipboard(); clip->setImage(toQImage()); OP_END}/** Create new image by pasting from clipboard @return Image with clipboard data or NULL if clipboard is empty or in wrong format*/Image* Image::loadFromPaste() { QClipboard *clip=QApplication::clipboard(); QImage img=clip->image(); if (img.isNull()) return NULL; return new Image(img);}/** default destructor */Image::~Image() { delete d;}/** Return CImg version*/QString Image::cimgVersion() { return QString::number((double)(cimg_version)/100.0,'f',2);}/** Return info about CImg features*/QString Image::cimgInfo() { QString out=""; out+=QObject::tr("Using PNG library")+" : "+#ifdef cimg_use_png QObject::tr("Yes");#else QObject::tr("No");#endif out+="<br>"+QObject::tr("Using JPEG library")+" : "+#ifdef cimg_use_jpeg QObject::tr("Yes");#else QObject::tr("No");#endif out+="<br>"+QObject::tr("Using TIFF library")+" : "+#ifdef cimg_use_tiff QObject::tr("Yes");#else QObject::tr("No");#endif out+="<br>"+QObject::tr("Using Magick++ library")+" : "+#ifdef cimg_use_magick QObject::tr("Yes");#else QObject::tr("No");#endif out+="<br>"+QObject::tr("Using FFTW3 library")+" : "+#ifdef cimg_use_fftw3 QObject::tr("Yes");#else QObject::tr("No");#endif out+="<br>"+QObject::tr("Path to ImageMagick")+" : "+cimg::imagemagick_path(); out+="<br>"+QObject::tr("Path to GraphicsMagick")+" : "+cimg::graphicsmagick_path(); out+="<br>"+QObject::tr("Path of 'medcon'")+" : "+cimg::medcon_path(); out+="<br>"+QObject::tr("Temporary path")+" : "+cimg::temporary_path(); return out;}} // namespace gui
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -