⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cimage.cpp

📁 Gambas is a graphical development environment based on a Basic interpreter, like Visual Basic. It us
💻 CPP
字号:
/***************************************************************************  CPicture.cpp  The Picture class  (c) 2000-2003 Beno顃 Minisini <gambas@users.sourceforge.net>  This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 1, or (at your option)  any later version.  This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.  You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.***************************************************************************/#define __CIMAGE_CPP#include <string.h>#include <qpixmap.h>#include <qbitmap.h>#include <qpicture.h>#include <qnamespace.h>#include <qdict.h>#include <qpainter.h>#include <qwmatrix.h>#include "gambas.h"#include "CPicture.h"#include "CImage.h"//#if QT_VERSION < 0x030100//#include <X11/Xlib.h>//#endifstatic void create(CIMAGE **pimage){  static GB_CLASS class_id = NULL;  if (!class_id)    class_id = GB.FindClass("Image");  GB.New((void **)pimage, class_id, NULL, NULL);}const char *CIMAGE_get_format(QString path){  int pos;  pos = path.findRev('.');  if (pos < 0)    return NULL;  path = path.mid(pos + 1).lower();  if (path == "png")    return "PNG";  else if (path == "jpg" || path == "jpeg")    return "JPEG";  else if (path == "gif")    return "GIF";  else if (path == "bmp")    return "BMP";  else if (path == "xpm")    return "XPM";  else    return NULL;}bool CIMAGE_load_image(QImage &p, char *path, long lenp){  char *addr;  long len;  bool ok = false;  if (!GB.LoadFile(path, lenp, &addr, &len))  {    ok = p.loadFromData((const uchar *)addr, (uint)len);    if (ok)    {      //create((CIMAGE **)&_object);      if (p.depth() < 32)        p = p.convertDepth(32);      p.setAlphaBuffer(true);    }    GB.ReleaseFile(&addr, len);  }  return ok;}#if 0static void create_new(CPICTURE **ppict){  *ppict = NULL;  create(ppict);}static bool load(CPICTURE **ppict, char *file){  FORMAT_MATCH *fmt;  bool ok;  char *addr;  long len;  CPICTURE *pict;  //qDebug("Loading %s", file);  if (GB.LoadFile(file, 0, &addr, &len))    return true;  QImage p;  ok = p.loadFromData((const uchar *)addr, (uint)len);  if (ok)  {    GB.New((void **)ppict, class_id, NULL, NULL);    create(ppict);    pict = *ppict;    clear(pict);    pict->image = new QImage;    //qDebug("%s: w = %d h = %d", file, p.width(), p.height());    if (p.depth() < 32)    {      //qDebug("Convert to depth 32");      *(pict->image) = p.convertDepth(32);      //delete pict->image;      //pict->image = p;    }    else      *(pict->image) = p;    pict->image->setAlphaBuffer(true);  }  GB.ReleaseFile(&addr, len);  if (!ok)    GB.Error("Unable to load image");  //qDebug("Loading %s => %s", file, ok ? "OK" : "*ERR*");  return !ok;}static CPICTURE *get_picture(char *key){  CPICTURE *pict;  pict = dict[key];  if (!pict)  {    create_new(&pict);    if (load(&pict, key))    {      GB.Unref((void **)&pict);      return NULL;    }    // Optimize for using in the interface    if (get_type(pict) == TYPE_IMAGE)      set_type(pict, TYPE_PIXMAP);    GB.Ref(pict);    dict.insert(key, pict);  }  return pict;}static void set_picture(char *key, CPICTURE *new_pict){  CPICTURE *pict;  pict = dict[key];  if (!pict)    GB.Unref((void **)&pict);  if (new_pict)    dict.replace(key, new_pict);}static void flush_picture(){  QDictIterator<CPICTURE> it(dict);  CPICTURE *pict;  while (it.current())  {    //delete it.current()->pixmap;    pict = it.current();    GB.Unref((void **)&pict);    ++it;  }}static int get_width(CPICTURE *_object){  if (CPICTURE_is_pixmap(THIS))    return THIS->pixmap->width();  else if (CPICTURE_is_image(THIS))    return THIS->image->width();  else if (CPICTURE_is_picture(THIS))    return THIS->picture->boundingRect().width();  else    return 0;}static int get_height(CPICTURE *_object){  if (CPICTURE_is_pixmap(THIS))    return THIS->pixmap->height();  else if (CPICTURE_is_image(THIS))    return THIS->image->height();  else if (CPICTURE_is_picture(THIS))    return THIS->picture->boundingRect().height();  else    return 0;}CPICTURE *CPICTURE_grab(int wid){  CPICTURE *pict;  #if QT_VERSION >= 0x030100  if (wid == 0)    wid = QPaintDevice::x11AppRootWindow();  #else  if (wid == 0)    wid = RootWindow(QPaintDevice::x11AppDisplay(), QPaintDevice::x11AppScreen());  #endif  create_new(&pict);  pict->pixmap = new QPixmap();  *pict->pixmap = QPixmap::grabWindow(wid);  return pict;}void CPICTURE_update_mask(CPICTURE *_object){  if (THIS->pixmap && THIS->pixmap->hasAlpha())    THIS->pixmap->setMask(THIS->pixmap->createHeuristicMask());}#endif/*******************************************************************************  Image*******************************************************************************/BEGIN_METHOD(CIMAGE_new, GB_INTEGER w; GB_INTEGER h)  int w, h;  THIS->image = new QImage();  w = VARGOPT(w, 0);  h = VARGOPT(h, 0);  if (h <= 0)    h = w;  else if (w <= 0)    w = h;  if (w > 0 && h > 0)  {    THIS->image->create(w, h, 32);    THIS->image->setAlphaBuffer(true);  }END_METHODBEGIN_METHOD_VOID(CIMAGE_free)  delete THIS->image;  THIS->image = 0;END_METHODBEGIN_PROPERTY(CIMAGE_picture)  CPICTURE *pict;  GB.New((void **)&pict, GB.FindClass("Picture"), NULL, NULL);  pict->pixmap->convertFromImage(*(THIS->image));  GB.ReturnObject(pict);END_PROPERTYBEGIN_METHOD(CIMAGE_resize, GB_INTEGER width; GB_INTEGER height)  if (THIS->image->isNull())  {    THIS->image->create(VARG(width), VARG(height), 32);    THIS->image->setAlphaBuffer(true);  }  else  {    QImage img = THIS->image->copy(0, 0, VARG(width), VARG(height));    delete THIS->image;    THIS->image = new QImage(img);  }END_METHODBEGIN_PROPERTY(CIMAGE_width)  GB.ReturnInteger(THIS->image->width());END_PROPERTYBEGIN_PROPERTY(CIMAGE_height)  GB.ReturnInteger(THIS->image->height());END_PROPERTYBEGIN_PROPERTY(CIMAGE_depth)  if (READ_PROPERTY)    GB.ReturnInteger(THIS->image->depth());  else  {    if (!THIS->image->isNull())    {      int depth = VPROP(GB_INTEGER);      if (depth != THIS->image->depth())      {        QImage img = THIS->image->convertDepth(depth);        if (!img.isNull())        {          delete THIS->image;          THIS->image = new QImage(img);        }      }    }  }END_PROPERTYBEGIN_METHOD(CIMAGE_load, GB_STRING path)  QImage p;  if (CIMAGE_load_image(p, STRING(path), LENGTH(path)))    *(THIS->image) = p;  else    GB.Error("Unable to load image");END_METHODBEGIN_METHOD(CIMAGE_save, GB_STRING path)  QString path = TO_QSTRING(GB.FileName(STRING(path), LENGTH(path)));  bool ok = false;  const char *fmt = CIMAGE_get_format(path);  if (!fmt)  {    GB.Error("Unknown format");    return;  }  ok = THIS->image->save(path, fmt);  if (!ok)    GB.Error("Unable to save picture");END_METHODBEGIN_METHOD_VOID(CIMAGE_clear)  delete THIS->image;  THIS->image = new QImage();END_METHODBEGIN_METHOD(CIMAGE_fill, GB_INTEGER col)  //bool a;  int col = VARG(col);  //a = THIS->image->hasAlphaBuffer();  THIS->image->setAlphaBuffer(false);  col ^= 0xFF000000;  THIS->image->fill(col);  THIS->image->setAlphaBuffer(true);END_METHODBEGIN_METHOD(CIMAGE_copy, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)  CIMAGE *img;  int x = VARGOPT(x, 0);  int y = VARGOPT(y, 0);  int w = VARGOPT(w, THIS->image->width());  int h = VARGOPT(h, THIS->image->height());  create(&img);  img->image->create(w, h, 32);  bool a = THIS->image->hasAlphaBuffer();  THIS->image->setAlphaBuffer(false);  bitBlt(img->image, 0, 0, THIS->image, x, y, w, h);  THIS->image->setAlphaBuffer(a);  img->image->setAlphaBuffer(a);  GB.ReturnObject(img);END_METHODBEGIN_METHOD(CIMAGE_stretch, GB_INTEGER width; GB_INTEGER height; GB_BOOLEAN smooth)  CIMAGE *img;  QImage stretch;  create(&img);  if (VARGOPT(smooth, TRUE))    *(img->image) = THIS->image->smoothScale(VARG(width), VARG(height));  else    *(img->image) = THIS->image->scale(VARG(width), VARG(height));  GB.ReturnObject(img);END_METHODBEGIN_METHOD_VOID(CIMAGE_flip)  CIMAGE *img;  create(&img);  *(img->image) = THIS->image->mirror(true, false);  GB.ReturnObject(img);END_METHODBEGIN_METHOD_VOID(CIMAGE_mirror)  CIMAGE *img;  create(&img);  *(img->image) = THIS->image->mirror(false, true);  GB.ReturnObject(img);END_METHODBEGIN_METHOD(CIMAGE_rotate, GB_FLOAT angle)  CIMAGE *img;  QWMatrix mat;  create(&img);  mat.rotate(VARG(angle));  *(img->image) = THIS->image->xForm(mat);  GB.ReturnObject(img);END_METHODBEGIN_METHOD(CIMAGE_replace, GB_INTEGER src; GB_INTEGER dst)  uint x, y, src, dst;  THIS->image->setAlphaBuffer(true);  src = VARG(src) ^ 0xFF000000;  dst = VARG(dst) ^ 0xFF000000;  for (y = 0; y < (uint)THIS->image->height(); y++)    for (x = 0; x < (uint)THIS->image->width(); x++)    {      if (THIS->image->pixel(x, y) != src)        continue;      THIS->image->setPixel(x, y, dst);    }END_METHOD/*******************************************************************************  .ImagePixels*******************************************************************************/BEGIN_METHOD(CIMAGE_pixels_get, GB_INTEGER x; GB_INTEGER y)  int col;  int x, y;  //unsigned char r, g, b, a;  x = VARG(x);  y = VARG(y);  if (!THIS->image->valid(x, y))  {    GB.ReturnInteger(-1);    return;  }  col = THIS->image->pixel(x, y) ^ 0xFF000000;  GB.ReturnInteger(col);  #if 0  a = (col >> 24);  //qDebug("[%d,%d] = (%d %d %d) / %d", x, y, r, g, b, a);  if (!THIS->image->hasAlphaBuffer() || a == 255)    GB.ReturnInteger( col & 0xFFFFFF);  else if (a == 0)    GB.ReturnInteger(-1);  else  {    r = col & 0xFF;    g = (col >> 8) & 0xFF;    b = (col >> 16) & 0xFF;    r = 255 - ((255 - r) * a) / 255;    g = 255 - ((255 - g) * a) / 255;    b = 255 - ((255 - b) * a) / 255;    GB.ReturnInteger(r + (g << 8) + (b << 16));  }  #endifEND_METHODBEGIN_METHOD(CIMAGE_pixels_put, GB_INTEGER col; GB_INTEGER x; GB_INTEGER y)  int x, y;  int col;  x = VARG(x);  y = VARG(y);  if (!THIS->image->valid(x, y))    return;  col = VARG(col) ^ 0xFF000000;  THIS->image->setPixel(x, y, col);END_METHOD#if 0BEGIN_PROPERTY(CPICTURE_pixels_data)  GB.ReturnInteger((long)THIS->image->bits());END_PROPERTY#endifGB_DESC CImageDesc[] ={  GB_DECLARE("Image", sizeof(CIMAGE)),  //GB_STATIC_METHOD("_exit", NULL, CPICTURE_flush, NULL),  //GB_CONSTANT("None", "i", TYPE_NONE),  //GB_CONSTANT("Bitmap", "i", TYPE_PIXMAP),  //GB_CONSTANT("Pixmap", "i", TYPE_PIXMAP),  //GB_CONSTANT("Vector", "i", TYPE_PICTURE),  //GB_CONSTANT("Metafile", "i", TYPE_PICTURE),  //GB_CONSTANT("Image", "i", TYPE_IMAGE),  GB_METHOD("_new", NULL, CIMAGE_new, "[(Width)i(Height)i]"),  GB_METHOD("_free", NULL, CIMAGE_free, NULL),  GB_METHOD("_get", "i", CIMAGE_pixels_get, "(X)i(Y)i"),  GB_METHOD("_put", NULL, CIMAGE_pixels_put, "(Color)i(X)i(Y)i"),  //GB_STATIC_METHOD("_get", "Picture", CPICTURE_get, "(Path)s"),  //GB_STATIC_METHOD("_put", NULL, CPICTURE_put, "(Picture)Picture;(Path)s"),  //GB_STATIC_METHOD("Flush", NULL, CPICTURE_flush, NULL),  //GB_PROPERTY("Type", "i<Picture,None,Pixmap,Image,Metafile>", CPICTURE_type),  GB_PROPERTY_READ("Width", "i", CIMAGE_width),  GB_PROPERTY_READ("Height", "i", CIMAGE_height),  GB_PROPERTY("Depth", "i", CIMAGE_depth),  GB_METHOD("Load", NULL, CIMAGE_load, "(Path)s"),  GB_METHOD("Save", NULL, CIMAGE_save, "(Path)s"),  GB_METHOD("Resize", NULL, CIMAGE_resize, "(Width)i(Height)i"),  GB_METHOD("Clear", NULL, CIMAGE_clear, NULL),  GB_METHOD("Fill", NULL, CIMAGE_fill, "(Color)i"),  GB_METHOD("Replace", NULL, CIMAGE_replace, "(OldColor)i(NewColor)i"),  //GB_METHOD("Mask", NULL, CPICTURE_mask, "[(Color)i]"),  GB_METHOD("Copy", "Image", CIMAGE_copy, "[(X)i(Y)i(Width)i(Height)i]"),  GB_METHOD("Stretch", "Image", CIMAGE_stretch, "(Width)i(Height)i[(Smooth)b]"),  GB_METHOD("Flip", "Image", CIMAGE_flip, NULL),  GB_METHOD("Mirror", "Image", CIMAGE_mirror, NULL),  GB_METHOD("Rotate", "Image", CIMAGE_rotate, "(Angle)f"),  GB_PROPERTY_READ("Picture", "Picture", CIMAGE_picture),  //GB_PROPERTY_SELF("Pixels", ".ImagePixels"),  //GB_PROPERTY_SELF("Colors", ".PictureColors"),  GB_END_DECLARE};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -