void GLWidget::draw()
{
    QPainter p(this); // used for text overlay

    // save the GL state set for QPainter
    p.beginNativePainting();
    saveGLState();

    // render the 'bubbles.svg' file into our pbuffer
    QPainter pbuffer_painter(pbuffer);
    svg_renderer->render(&pbuffer_painter);
    pbuffer_painter.end();
    glFlush();

    // rendering directly to a texture is not supported on X11 and
    // some Windows implementations, unfortunately
    if (!hasDynamicTextureUpdate)
        pbuffer->updateDynamicTexture(dynamicTexture);

    makeCurrent();
    // draw into the GL widget
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1, 1, -1, 1, 10, 100);
    glTranslatef(0.0f, 0.0f, -15.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glViewport(0, 0, width(), height());

    glBindTexture(GL_TEXTURE_2D, dynamicTexture);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_MULTISAMPLE);
    glEnable(GL_CULL_FACE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    // draw background
    glPushMatrix();
    glScalef(1.7f, 1.7f, 1.7f);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    glCallList(tile_list);
    glPopMatrix();

    const int w = logo.width();
    const int h = logo.height();

    glRotatef(rot_x, 1.0f, 0.0f, 0.0f);
    glRotatef(rot_y, 0.0f, 1.0f, 0.0f);
    glRotatef(rot_z, 0.0f, 0.0f, 1.0f);
    glScalef(scale/w, scale/w, scale/w);

    glDepthFunc(GL_LESS);
    glEnable(GL_DEPTH_TEST);

    // draw the Qt icon
    glTranslatef(-w+1, -h+1, 0.0f);
    for (int y=h-1; y>=0; --y) {
        uint *p = (uint*) logo.scanLine(y);
        uint *end = p + w;
        int  x = 0;
        while (p < end) {
            glColor4ub(qRed(*p), qGreen(*p), qBlue(*p), uchar(qAlpha(*p)*.9));
            glTranslatef(0.0f, 0.0f, wave[y*w+x]);
            if (qAlpha(*p) > 128)
                glCallList(tile_list);
            glTranslatef(0.0f, 0.0f, -wave[y*w+x]);
            glTranslatef(2.0f, 0.0f, 0.0f);
            ++x;
            ++p;
        }
        glTranslatef(-w*2.0f, 2.0f, 0.0f);
    }

    // restore the GL state that QPainter expects
    restoreGLState();
    p.endNativePainting();

    // draw the overlayed text using QPainter
    p.setPen(QColor(197, 197, 197, 157));
    p.setBrush(QColor(197, 197, 197, 127));
    p.drawRect(QRect(0, 0, width(), 50));
    p.setPen(Qt::black);
    p.setBrush(Qt::NoBrush);
    const QString str1(tr("A simple OpenGL pbuffer example."));
    const QString str2(tr("Use the mouse wheel to zoom, press buttons and move mouse to rotate, double-click to flip."));
    QFontMetrics fm(p.font());
    p.drawText(width()/2 - fm.width(str1)/2, 20, str1);
    p.drawText(width()/2 - fm.width(str2)/2, 20 + fm.lineSpacing(), str2);
}
示例#2
0
bool QgsHttpRequestHandler::greenCompare( QPair<QRgb, int> c1, QPair<QRgb, int> c2 )
{
  return qGreen( c1.first ) < qGreen( c2.first );
}
示例#3
0
void ImageOperations::featureScale( const OpGrayImage& img,
                                    OpGrayImage& imgRet )
{

  QImage qimg = img.getQtImage();

  QImage qimgRet;
  qimgRet.create(qimg.width()/2, qimg.height()/2, 32);

  for( int y=0; y<qimg.height(); y+=2 )
  {
    for( int x=0; x<qimg.width(); x+=2 )
    {
      if( (int(x/2) < qimgRet.width()) && (int(y/2) < qimgRet.height()))
      {
        if( (qRed  (qimg.pixel(x,y)) == 0) &&      // If pixel in
            (qGreen(qimg.pixel(x,y)) == 0) &&      //  image contains feature
            (qBlue (qimg.pixel(x,y)) == 0))
        {      //  set in scaled
          qimgRet.setPixel(int(x/2), int(y/2), qRgb(0,0,0));

        }
        else
        {
          if ((x < qimg.width()-1) &&                // Else, if pixel
              ((qRed  (qimg.pixel(x+1,y)) == 0) &&   //  to the right
               (qGreen(qimg.pixel(x+1,y)) == 0) &&   //  contains feature
               (qBlue (qimg.pixel(x+1,y)) == 0)))
          {  //  set in scaled.
            qimgRet.setPixel(int(x/2), int(y/2), qRgb(0,0,0));

          }
          else
          {
            if( (y < qimg.height()-1) &&                    // Else if pixel
                ((qRed  (qimg.pixel(x,y+1)) == 0) &&        //  below contains
                 (qGreen(qimg.pixel(x,y+1)) == 0) &&        //  feature, set
                 (qBlue (qimg.pixel(x,y+1)) == 0)))
            {       //  in scaled.
              qimgRet.setPixel(int(x/2), int(y/2), qRgb(0,0,0));

            }
            else
            {                                      // Else if pixel
              if( ((x < qimg.width()-1) &&                //  to the right
                   (y < qimg.height()-1)) &&              //  and below
                  ((qRed  (qimg.pixel(x,y+1)) == 0) &&    //  contains
                   (qGreen(qimg.pixel(x,y+1)) == 0) &&    //  feature, set
                   (qBlue (qimg.pixel(x,y+1)) == 0)))
              {   //  it in scaled.
                qimgRet.setPixel(int(x/2), int(y/2), qRgb(0,0,0));

              }
              else
              {                                    // Else set
                qimgRet.setPixel(int(x/2), int(y/2),      // non-feature in
                                 qRgb(255,255,255));      //  scaled.
              }
            }
          }
        }
      }
    }
  }

  OpGrayImage tmp(qimgRet);
  imgRet = tmp;
}
示例#4
0
void RGBMatrix::updateMapChannels(const RGBMap& map, const FixtureGroup* grp)
{
    quint32 mdAssigned = QLCChannel::invalid();
    quint32 mdFxi = Fixture::invalidId();

    uint fadeTime = 0;
    if (overrideFadeInSpeed() == defaultSpeed())
        fadeTime = fadeInSpeed();
    else
        fadeTime = overrideFadeInSpeed();

    // Create/modify fade channels for ALL pixels in the color map.
    for (int y = 0; y < map.size(); y++)
    {
        for (int x = 0; x < map[y].size(); x++)
        {
            QLCPoint pt(x, y);
            GroupHead grpHead(grp->head(pt));
            Fixture* fxi = doc()->fixture(grpHead.fxi);
            if (fxi == NULL)
                continue;

            if (grpHead.fxi != mdFxi)
            {
                mdAssigned = QLCChannel::invalid();
                mdFxi = grpHead.fxi;
            }

            QLCFixtureHead head = fxi->head(grpHead.head);

            QVector <quint32> rgb = head.rgbChannels();
            QVector <quint32> cmy = head.cmyChannels();
            if (rgb.size() == 3)
            {
                // RGB color mixing
                FadeChannel fc;
                fc.setFixture(doc(), grpHead.fxi);

                fc.setChannel(rgb.at(0));
                fc.setTarget(qRed(map[y][x]));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(rgb.at(1));
                fc.setTarget(qGreen(map[y][x]));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(rgb.at(2));
                fc.setTarget(qBlue(map[y][x]));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
            }
            else if (cmy.size() == 3)
            {
                // CMY color mixing
                QColor col(map[y][x]);

                FadeChannel fc;
                fc.setFixture(doc(), grpHead.fxi);

                fc.setChannel(cmy.at(0));
                fc.setTarget(col.cyan());
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(cmy.at(1));
                fc.setTarget(col.magenta());
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);

                fc.setChannel(cmy.at(2));
                fc.setTarget(col.yellow());
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
            }

            if (head.masterIntensityChannel() != QLCChannel::invalid())
            {
                //qDebug() << "RGBMatrix: found dimmer at" << head.masterIntensityChannel();
                // Simple intensity (dimmer) channel
                QColor col(map[y][x]);
                FadeChannel fc;
                fc.setFixture(doc(), grpHead.fxi);
                fc.setChannel(head.masterIntensityChannel());
                if (col.value() == 0 && mdAssigned != head.masterIntensityChannel())
                    fc.setTarget(0);
                else
                {
                    fc.setTarget(255);
                    if (mdAssigned == QLCChannel::invalid())
                        mdAssigned = head.masterIntensityChannel();
                }
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
            }
        }
    }
}
示例#5
0
static bool write_pbm_image(QIODevice *out, const QImage &sourceImage, const QByteArray &sourceFormat)
{
    QByteArray str;
    QImage image = sourceImage;
    QByteArray format = sourceFormat;

    format = format.left(3);                        // ignore RAW part
    bool gray = format == "pgm";

    if (format == "pbm") {
        image = image.convertToFormat(QImage::Format_Mono);
    } else if (image.depth() == 1) {
        image = image.convertToFormat(QImage::Format_Indexed8);
    } else {
        switch (image.format()) {
        case QImage::Format_RGB16:
        case QImage::Format_RGB666:
        case QImage::Format_RGB555:
        case QImage::Format_RGB888:
        case QImage::Format_RGB444:
            image = image.convertToFormat(QImage::Format_RGB32);
            break;
        case QImage::Format_ARGB8565_Premultiplied:
        case QImage::Format_ARGB6666_Premultiplied:
        case QImage::Format_ARGB8555_Premultiplied:
        case QImage::Format_ARGB4444_Premultiplied:
            image = image.convertToFormat(QImage::Format_ARGB32);
            break;
        default:
            break;
        }
    }

    if (image.depth() == 1 && image.colorCount() == 2) {
        if (qGray(image.color(0)) < qGray(image.color(1))) {
            // 0=dark/black, 1=light/white - invert
            image.detach();
            for (int y=0; y<image.height(); y++) {
                uchar *p = image.scanLine(y);
                uchar *end = p + image.bytesPerLine();
                while (p < end)
                    *p++ ^= 0xff;
            }
        }
    }

    uint w = image.width();
    uint h = image.height();

    str = "P\n";
    str += QByteArray::number(w);
    str += ' ';
    str += QByteArray::number(h);
    str += '\n';

    switch (image.depth()) {
        case 1: {
            str.insert(1, '4');
            if (out->write(str, str.length()) != str.length())
                return false;
            w = (w+7)/8;
            for (uint y=0; y<h; y++) {
                uchar* line = image.scanLine(y);
                if (w != (uint)out->write((char*)line, w))
                    return false;
            }
            }
            break;

        case 8: {
            str.insert(1, gray ? '5' : '6');
            str.append("255\n");
            if (out->write(str, str.length()) != str.length())
                return false;
            QVector<QRgb> color = image.colorTable();
            uint bpl = w*(gray ? 1 : 3);
            uchar *buf   = new uchar[bpl];
            for (uint y=0; y<h; y++) {
                uchar *b = image.scanLine(y);
                uchar *p = buf;
                uchar *end = buf+bpl;
                if (gray) {
                    while (p < end) {
                        uchar g = (uchar)qGray(color[*b++]);
                        *p++ = g;
                    }
                } else {
                    while (p < end) {
                        QRgb rgb = color[*b++];
                        *p++ = qRed(rgb);
                        *p++ = qGreen(rgb);
                        *p++ = qBlue(rgb);
                    }
                }
                if (bpl != (uint)out->write((char*)buf, bpl))
                    return false;
            }
            delete [] buf;
            }
            break;

        case 32: {
            str.insert(1, gray ? '5' : '6');
            str.append("255\n");
            if (out->write(str, str.length()) != str.length())
                return false;
            uint bpl = w*(gray ? 1 : 3);
            uchar *buf = new uchar[bpl];
            for (uint y=0; y<h; y++) {
                QRgb  *b = (QRgb*)image.scanLine(y);
                uchar *p = buf;
                uchar *end = buf+bpl;
                if (gray) {
                    while (p < end) {
                        uchar g = (uchar)qGray(*b++);
                        *p++ = g;
                    }
                } else {
                    while (p < end) {
                        QRgb rgb = *b++;
                        *p++ = qRed(rgb);
                        *p++ = qGreen(rgb);
                        *p++ = qBlue(rgb);
                    }
                }
                if (bpl != (uint)out->write((char*)buf, bpl))
                    return false;
            }
            delete [] buf;
            }
            break;

    default:
        return false;
    }

    return true;
}
示例#6
0
bool VoxelTree::readFromSquareARGB32Pixels(const char* filename) {
    emit importProgress(0);
    int minAlpha = INT_MAX;

    QImage pngImage = QImage(filename);

    for (int i = 0; i < pngImage.width(); ++i) {
        for (int j = 0; j < pngImage.height(); ++j) {
            minAlpha = std::min(qAlpha(pngImage.pixel(i, j)) , minAlpha);
        }
    }

    int maxSize = std::max(pngImage.width(), pngImage.height());

    int scale = 1;
    while (maxSize > scale) {scale *= 2;}
    float size = 1.0f / scale;

    emit importSize(size * pngImage.width(), 1.0f, size * pngImage.height());

    QRgb pixel;
    int minNeighborhoodAlpha;

    for (int i = 0; i < pngImage.width(); ++i) {
        for (int j = 0; j < pngImage.height(); ++j) {
            emit importProgress((100 * (i * pngImage.height() + j)) /
                                (pngImage.width() * pngImage.height()));

            pixel = pngImage.pixel(i, j);
            minNeighborhoodAlpha = qAlpha(pixel) - 1;

            if (i != 0) {
                minNeighborhoodAlpha = std::min(minNeighborhoodAlpha, qAlpha(pngImage.pixel(i - 1, j)));
            }
            if (j != 0) {
                minNeighborhoodAlpha = std::min(minNeighborhoodAlpha, qAlpha(pngImage.pixel(i, j - 1)));
            }
            if (i < pngImage.width() - 1) {
                minNeighborhoodAlpha = std::min(minNeighborhoodAlpha, qAlpha(pngImage.pixel(i + 1, j)));
            }
            if (j < pngImage.height() - 1) {
                minNeighborhoodAlpha = std::min(minNeighborhoodAlpha, qAlpha(pngImage.pixel(i, j + 1)));
            }

            while (qAlpha(pixel) > minNeighborhoodAlpha) {
                ++minNeighborhoodAlpha;
                createVoxel(i * size,
                            (minNeighborhoodAlpha - minAlpha) * size,
                            j * size,
                            size,
                            qRed(pixel),
                            qGreen(pixel),
                            qBlue(pixel),
                            true);
            }

        }
    }

    emit importProgress(100);
    return true;
}
示例#7
0
void renderWatermark(QImage & image, const QString & wmText, const QFont & wmFont, const unsigned int wmOpacity, double pA, double pB, double pC, double pD)
{
  const double pi = 3.14159265358979323846;

  double w = ((double)image.width() - pA);
  double h = ((double)image.height() - pB);
  double theta = (pi/-2.0) + atan(w / h);
  double l = sqrt((w * w) + (h * h));

  const double sintheta = sin(theta);
  const double costheta = cos(theta);

  double margin_width = pC;
  double margin_height = pD;

  int offset = (int)(l * 0.05);
  int l2 = (int)(l * 0.9);

  int x = (int)(sintheta * h) + offset;
  int y = (int)(costheta * h);

  QFont fnt = wmFont;
  QFontMetrics fm = QFontMetrics(fnt);
  QFontInfo fi(fnt);
  QString family = fi.family();
  QList<int> sizes = QFontDatabase().pointSizes(family);
  qSort(sizes);

  for(int i = sizes.size() - 1; i > 0; i--)
  {
    fnt.setPointSize(sizes[i]);
    fm = QFontMetrics(fnt);
    if(fm.boundingRect(wmText).width() < l2)
      break;
  }
  int fh = fm.height();

  y = y - (fh/2);

  //NB QPixmap not safe outside of main thread, using QImage instead
  QImage wm(image.width(), image.height(), QImage::Format_RGB32);
  wm.fill(0xFFFFFFFF);
  QPainter pPainter;
  pPainter.begin(&wm);
  pPainter.setFont(fnt);
  pPainter.translate(margin_width, margin_height);
  pPainter.rotate((theta/pi)*180);
  pPainter.drawText(x, y, l2, fh, Qt::AlignCenter, wmText);
  pPainter.end();

  double opacity = wmOpacity / 255.0;
  double opacity_inv = 1.0 - opacity;

  QRgb s = 0;
  QRgb d = 0;
  for(y = 0; y < image.height(); y++) {
    for(x = 0; x < image.width(); x++) {
      s = wm.pixel(x, y);
      if((s & 0x00ffffff) == 0x00ffffff) continue; // if it's white just skip it
      d = image.pixel(x, y);
      image.setPixel(x, y, qRgb( (int)((qRed(s) * opacity) + (qRed(d) * opacity_inv)),
                                 (int)((qGreen(s) * opacity) + (qGreen(d) * opacity_inv)),
                                 (int)((qBlue(s) * opacity) + (qBlue(d) * opacity_inv)) ));
    }
  }
}
示例#8
0
QPixmap MIconEngine::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state)
      {
      QPixmap pm;

      QString pmckey(d->pmcKey(size, mode, state));
      if (QPixmapCache::find(pmckey, pm))
            return pm;

      if (d->addedPixmaps) {
            pm = d->addedPixmaps->value(d->hashKey(mode, state));
            if (!pm.isNull() && pm.size() == size)
                  return pm;
            }

      QSvgRenderer renderer;
      d->loadDataForModeAndState(&renderer, mode, state);
      if (!renderer.isValid())
            return pm;

      QSize actualSize = renderer.defaultSize();
      if (!actualSize.isNull())
            actualSize.scale(size, Qt::KeepAspectRatio);

      QImage img(actualSize, QImage::Format_ARGB32);
      img.fill(0x00000000);
      QPainter p(&img);
      renderer.render(&p);
      p.end();

      bool light = Ms::preferences.globalStyle == Ms::STYLE_LIGHT;

      int ww = img.width();
      if (state == QIcon::On) {
            if (light) {
                  for (int y = 0; y < img.height(); ++y) {
                        QRgb *scanLine = (QRgb*)img.scanLine(y);
                        for (int x = 0; x < img.width(); ++x) {
                              QRgb pixel = *scanLine;
                              int alpha = qAlpha(pixel);
                              if (alpha < 0)
                                    alpha = 0;
                              *scanLine = qRgba(qRed(255-pixel), qGreen(255-pixel), qBlue(255-pixel), alpha);
                              ++scanLine;
                              }
                        }
                  }
            else {
                  for (int y = 0; y < img.height(); ++y) {
                        quint32* p = (quint32*)img.scanLine(y);
                        for (int x = 0; x < ww; ++x) {
                              if (*p & 0xff000000) {
                                    int d = 0xff - (*p & 0xff);
                                    int dd = 50;
                                    QColor color(QColor::fromRgba(*p));
                                    int r = 70 - d + dd;
                                    if (r < 0)
                                          r = 0;
                                    int g = 130 - d + dd;
                                    if (g < 0)
                                          g = 0;
                                    int b = 180 - d + dd;
                                    if (b < 0)
                                          b = 0;
                                    QColor nc = QColor(r, g, b, color.alpha());
                                    *p = nc.rgba();
                                    }
                              ++p;
                              }
                        }
                  }
            }
      else {
            // change alpha channel
            int delta = 51;
            if (mode == QIcon::Disabled)
                  delta = 178;
            else if (state == QIcon::On)
                  delta = 0;
            if (light) {
                  for (int y = 0; y < img.height(); ++y) {
                        QRgb *scanLine = (QRgb*)img.scanLine(y);
                        for (int x = 0; x < img.width(); ++x) {
                              QRgb pixel = *scanLine;
                              int alpha = qAlpha(pixel) - delta;
                              if (alpha < 0)
                                    alpha = 0;
                              *scanLine = qRgba(qRed(255-pixel), qGreen(255-pixel), qBlue(255-pixel), alpha);
                              ++scanLine;
                              }
                        }
                  }
            else {
                  for (int y = 0; y < img.height(); ++y) {
                        QRgb *scanLine = (QRgb*)img.scanLine(y);
                        for (int x = 0; x < img.width(); ++x) {
                              QRgb pixel = *scanLine;
                              int alpha = qAlpha(pixel) - delta;
                              if (alpha < 0)
                                    alpha = 0;
                              *scanLine = qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), alpha);
                              ++scanLine;
                              }
                        }
                  }
            }

      pm = QPixmap::fromImage(img);
      if (!pm.isNull())
            QPixmapCache::insert(pmckey, pm);
      return pm;
      }
QgsRasterBlock * QgsBrightnessContrastFilter::block( int bandNo, QgsRectangle  const & extent, int width, int height )
{
  Q_UNUSED( bandNo );
  QgsDebugMsg( QString( "width = %1 height = %2 extent = %3" ).arg( width ).arg( height ).arg( extent.toString() ) );

  QgsRasterBlock *outputBlock = new QgsRasterBlock();
  if ( !mInput )
  {
    return outputBlock;
  }

  // At this moment we know that we read rendered image
  int bandNumber = 1;
  QgsRasterBlock *inputBlock = mInput->block( bandNumber, extent, width, height );
  if ( !inputBlock || inputBlock->isEmpty() )
  {
    QgsDebugMsg( "No raster data!" );
    delete inputBlock;
    return outputBlock;
  }

  if ( mBrightness == 0 && mContrast == 0 )
  {
    QgsDebugMsg( "No brightness changes." );
    delete outputBlock;
    return inputBlock;
  }

  if ( !outputBlock->reset( QGis::ARGB32_Premultiplied, width, height ) )
  {
    delete inputBlock;
    return outputBlock;
  }

  // adjust image
  QRgb myNoDataColor = qRgba( 0, 0, 0, 0 );
  QRgb myColor;

  int r, g, b, alpha;
  double f = qPow(( mContrast + 100 ) / 100.0, 2 );

  for ( qgssize i = 0; i < ( qgssize )width*height; i++ )
  {
    if ( inputBlock->color( i ) == myNoDataColor )
    {
      outputBlock->setColor( i, myNoDataColor );
      continue;
    }

    myColor = inputBlock->color( i );
    alpha = qAlpha( myColor );

    r = adjustColorComponent( qRed( myColor ), alpha, mBrightness, f );
    g = adjustColorComponent( qGreen( myColor ), alpha, mBrightness, f );
    b = adjustColorComponent( qBlue( myColor ), alpha, mBrightness, f );

    outputBlock->setColor( i, qRgba( r, g, b, alpha ) );
  }

  delete inputBlock;
  return outputBlock;
}
示例#10
0
void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format format, int width, int height )
{
	// Obtain properties of frame and producer
	mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
	mlt_producer producer = &self->parent;

	// Get index and qimage
	int image_idx = refresh_qimage( self, frame );

	// optimization for subsequent iterations on single pictur
	if ( image_idx != self->image_idx || width != self->current_width || height != self->current_height )
		self->current_image = NULL;

	// If we have a qimage and need a new scaled image
	if ( self->qimage && ( !self->current_image || ( format != mlt_image_none  && format != self->format ) ) )
	{
		QString interps = mlt_properties_get( properties, "rescale.interp" );
		bool interp = ( interps != "nearest" ) && ( interps != "none" );
		QImage *qimage = static_cast<QImage*>( self->qimage );

		// Note - the original qimage is already safe and ready for destruction
		if ( qimage->depth() == 1 )
		{
			QImage temp = qimage->convertToFormat( QImage::Format_RGB32 );
			delete qimage;
			qimage = new QImage( temp );
			self->qimage = qimage;
		}
		QImage scaled = interp? qimage->scaled( QSize( width, height ) ) :
			qimage->scaled( QSize(width, height), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
		int has_alpha = scaled.hasAlphaChannel();

		// Store width and height
		self->current_width = width;
		self->current_height = height;

		// Allocate/define image
		int dst_stride = width * ( has_alpha ? 4 : 3 );
		int image_size = dst_stride * ( height + 1 );
		self->current_image = ( uint8_t * )mlt_pool_alloc( image_size );
		self->current_alpha = NULL;
		self->format = has_alpha ? mlt_image_rgb24a : mlt_image_rgb24;

		// Copy the image
		int y = self->current_height + 1;
		uint8_t *dst = self->current_image;
		while ( --y )
		{
			QRgb *src = (QRgb*) scaled.scanLine( self->current_height - y );
			int x = self->current_width + 1;
			while ( --x )
			{
				*dst++ = qRed(*src);
				*dst++ = qGreen(*src);
				*dst++ = qBlue(*src);
				if ( has_alpha ) *dst++ = qAlpha(*src);
				++src;
			}
		}

		// Convert image to requested format
		if ( format != mlt_image_none && format != self->format )
		{
			uint8_t *buffer = NULL;

			// First, set the image so it can be converted when we get it
			mlt_frame_replace_image( frame, self->current_image, self->format, width, height );
			mlt_frame_set_image( frame, self->current_image, image_size, mlt_pool_release );
			self->format = format;

			// get_image will do the format conversion
			mlt_frame_get_image( frame, &buffer, &format, &width, &height, 0 );

			// cache copies of the image and alpha buffers
			if ( buffer )
			{
				image_size = mlt_image_format_size( format, width, height, NULL );
				self->current_image = (uint8_t*) mlt_pool_alloc( image_size );
				memcpy( self->current_image, buffer, image_size );
			}
			if ( ( buffer = mlt_frame_get_alpha_mask( frame ) ) )
			{
				self->current_alpha = (uint8_t*) mlt_pool_alloc( width * height );
				memcpy( self->current_alpha, buffer, width * height );
			}
		}

		// Update the cache
		mlt_cache_item_close( self->image_cache );
		mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.image", self->current_image, image_size, mlt_pool_release );
		self->image_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.image" );
		self->image_idx = image_idx;
		mlt_cache_item_close( self->alpha_cache );
		self->alpha_cache = NULL;
		if ( self->current_alpha )
		{
			mlt_service_cache_put( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha", self->current_alpha, width * height, mlt_pool_release );
			self->alpha_cache = mlt_service_cache_get( MLT_PRODUCER_SERVICE( producer ), "qimage.alpha" );
		}
	}

	// Set width/height of frame
	mlt_properties_set_int( properties, "width", self->current_width );
	mlt_properties_set_int( properties, "height", self->current_height );
}
示例#11
0
void CSettings::read()
{
	QSettings settings(qApp->applicationDirPath() + "/settnig.ini", QSettings::IniFormat) ;
	qDebug() << "readRootSetting\n" << settings.allKeys() ;
	qDebug() << "file:" << qApp->applicationDirPath() + "/settnig.ini" ;

	settings.beginGroup("Global");
#if defined(Q_OS_WIN32)
	m_fileOpenDir = settings.value("cur_dir", QString(".\\")).toString() ;
#elif defined(Q_OS_MAC)
	m_fileOpenDir = settings.value("cur_dir", QString("/Users/")).toString() ;
#elif defined(Q_OS_LINUX)
	m_fileOpenDir = settings.value("cur_dir", QString("/home/")).toString() ;
#else
	#error OSが定義されてないよ
#endif
	m_fileSaveDir	= settings.value("save_dir", m_fileOpenDir).toString() ;
	m_pngSaveDir	= settings.value("png_dir", m_fileOpenDir).toString() ;
	m_jsonSaveDir	= settings.value("json_dir", m_fileOpenDir).toString() ;
	m_asmSaveDir	= settings.value("asm_dir", m_fileOpenDir).toString() ;

	QRgb col_anm = settings.value("anime_color", 0).toUInt() ;
	QRgb col_img = settings.value("image_color", 0).toUInt() ;
	m_animeBGColor		= QColor(qRed(col_anm), qGreen(col_anm), qBlue(col_anm), qAlpha(col_anm)) ;
	m_imageBGColor		= QColor(qRed(col_img), qGreen(col_img), qBlue(col_img), qAlpha(col_img)) ;
	m_bSaveImage		= settings.value("save_image", false).toBool() ;
	m_bFlat				= settings.value("save_flat_json", false).toBool() ;
	m_bLayerHierarchy	= settings.value("layer_hierarchy", false).toBool() ;
	m_frameStart		= settings.value("frame_start", 0).toInt() ;
	m_frameEnd			= settings.value("frame_end", 30).toInt() ;
	m_bBackup			= settings.value("backup", false).toBool() ;
	m_backupNum			= settings.value("backup_num", 1).toInt() ;
	settings.endGroup();

	settings.beginGroup("MainWindow");
	m_mainWindowGeometry	= settings.value("geometry").toByteArray() ;
	m_mainWindowState		= settings.value("state").toByteArray() ;
	settings.endGroup();

	settings.beginGroup("AnimationWindow");
	m_anmWindowGeometry			= settings.value("geometry").toByteArray() ;
	m_bUseBackImage				= settings.value("use_back_image", false).toBool() ;
	m_backImagePath				= settings.value("back_image", "").toString() ;
	m_bDrawFrame				= settings.value("disp_frame", true).toBool() ;
	m_bDrawCenter				= settings.value("disp_center", false).toBool() ;
	m_anmWindowTreeWidth		= settings.value("tree_width", -1).toInt() ;
	m_anmWindowTreeWidthIndex	= settings.value("tree_width_idx", -1).toInt() ;
	m_anmWindowScreenW			= settings.value("scr_w", 0).toInt() ;
	m_anmWindowScreenH			= settings.value("scr_h", 0).toInt() ;
	m_anmWindowW				= settings.value("win_w", 2048).toInt() ;
	m_anmWindowH				= settings.value("win_h", 2048).toInt() ;
	m_bUseDepthTest				= settings.value("use_depth_test", true).toBool() ;
	m_bUseZSort					= settings.value("use_zsort", true).toBool() ;
	m_bCheckGrid				= settings.value("check_grid", true).toBool() ;
	m_bCheckLinearFilter		= settings.value("check_linear_filter", false).toBool() ;
	settings.endGroup();

	settings.beginGroup("ImageWindow");
	m_imgWindowGeometry = settings.value("geometry").toByteArray() ;
	settings.endGroup();

	settings.beginGroup("LoupeWindow");
	m_loupeWindowGeometry = settings.value("geometry").toByteArray() ;
	settings.endGroup();

	settings.beginGroup("CurveEditorWindow") ;
	m_curveWindowGeometry		= settings.value("geometry").toByteArray() ;
	m_curveSplitterWidth		= settings.value("splitter_width", -1).toInt() ;
	m_curveSplitterWidthIndex	= settings.value("splitter_width_idx", -1).toInt() ;
	settings.endGroup() ;

	settings.beginGroup("Shortcut");
	m_scPosSelect		= QKeySequence(settings.value("pos", "Z").toString()) ;
	m_scRotSelect		= QKeySequence(settings.value("rot", "X").toString()) ;
	m_scCenterSelect	= QKeySequence(settings.value("center", "C").toString()) ;
	m_scScaleSelect		= QKeySequence(settings.value("scale", "V").toString()) ;
	m_scPathSelect		= QKeySequence(settings.value("path", "B").toString()) ;
	m_scCopyFrame		= QKeySequence(settings.value("copy_frame", "Ctrl+C").toString()) ;
	m_scPasteFrame		= QKeySequence(settings.value("paste_frame", "Ctrl+V").toString()) ;
	m_scPlayAnime		= QKeySequence(settings.value("play_anime", "").toString()) ;
	m_scStopAnime		= QKeySequence(settings.value("stop_anime", "").toString()) ;
	m_scJumpStartFrame	= QKeySequence(settings.value("jump_start", "").toString()) ;
	m_scJumpEndFrame	= QKeySequence(settings.value("jump_end", "").toString()) ;
	m_scAddFrameData	= QKeySequence(settings.value("add_frame", "").toString()) ;
	m_scDelFrameData	= QKeySequence(settings.value("del_frame", "").toString()) ;
	m_scDelItem			= QKeySequence(settings.value("del_item", "").toString()) ;
	m_scDispItem		= QKeySequence(settings.value("disp_item", "").toString()) ;
	m_scLockItem		= QKeySequence(settings.value("lock_item", "").toString()) ;
	m_scMoveAnimeWindow	= QKeySequence(settings.value("move_anm_win", "").toString()) ;
	m_scLockLoupe		= QKeySequence(settings.value("lock_loupe", "").toString()) ;
	m_scCopyAllFrame	= QKeySequence(settings.value("copy_allframe", "").toString()) ;
	m_scPasteAllFrame	= QKeySequence(settings.value("paste_allframe", "").toString()) ;
	m_scDeleteAllFrame	= QKeySequence(settings.value("delete_allframe", "").toString()) ;
	settings.endGroup();
}
示例#12
0
QImage HistogramGenerator::calculateHistogram(const QSize &paradeSize, const QImage &image, const int &components,
                                              HistogramGenerator::Rec rec, const bool &unscaled, const uint &accelFactor) const
{
    if (paradeSize.height() <= 0 || paradeSize.width() <= 0 || image.width() <= 0 || image.height() <= 0) {
        return QImage();
    }

    bool drawY = (components & HistogramGenerator::ComponentY) != 0;
    bool drawR = (components & HistogramGenerator::ComponentR) != 0;
    bool drawG = (components & HistogramGenerator::ComponentG) != 0;
    bool drawB = (components & HistogramGenerator::ComponentB) != 0;
    bool drawSum = (components & HistogramGenerator::ComponentSum) != 0;

    int r[256], g[256], b[256], y[256], s[766];
    // Initialize the values to zero
    std::fill(r, r+256, 0);
    std::fill(g, g+256, 0);
    std::fill(b, b+256, 0);
    std::fill(y, y+256, 0);
    std::fill(s, s+766, 0);

    const uint iw = image.bytesPerLine();
    const uint ih = image.height();
    const uint ww = paradeSize.width();
    const uint wh = paradeSize.height();
    const uint byteCount = iw*ih;
    const uint stepsize = 4*accelFactor;

    const uchar *bits = image.bits();
    QRgb *col;


    // Read the stats from the input image
    for (uint i = 0; i < byteCount; i += stepsize) {
        col = (QRgb *)bits;

        r[qRed(*col)]++;
        g[qGreen(*col)]++;
        b[qBlue(*col)]++;
        if (drawY) {
            // Use if branch to avoid expensive multiplication if Y disabled
            if (rec == HistogramGenerator::Rec_601) {
                y[(int)floor(.299*qRed(*col) + .587*qGreen(*col) + .114*qBlue(*col))]++;
            } else {
                y[(int)floor(.2125*qRed(*col) + .7154*qGreen(*col) + .0721*qBlue(*col))]++;
            }
        }
        if (drawSum) {
            // Use an if branch here because the sum takes more operations than rgb
            s[qRed(*col)]++;
            s[qGreen(*col)]++;
            s[qBlue(*col)]++;
        }

        bits += stepsize;
    }


    const int nParts = (drawY ? 1 : 0) + (drawR ? 1 : 0) + (drawG ? 1 : 0) + (drawB ? 1 : 0) + (drawSum ? 1 : 0);
    if (nParts == 0) {
        // Nothing to draw
        return QImage();
    }

    const int d = 20; // Distance for text
    const int partH = (wh-nParts*d)/nParts;
    const float scaling = (float)partH/(byteCount >> 7);
    const int dist = 40;

    int wy = 0; // Drawing position

    QImage histogram(paradeSize, QImage::Format_ARGB32);
    QPainter davinci(&histogram);
    davinci.setPen(QColor(220, 220, 220, 255));
    histogram.fill(qRgba(0, 0, 0, 0));

    if (drawY) {
        drawComponentFull(&davinci, y, scaling, QRect(0, wy, ww, partH + dist), QColor(220, 220, 210, 255), dist, unscaled, 256);

        wy += partH + d;
    }

    if (drawSum) {
        drawComponentFull(&davinci, s, scaling/3, QRect(0, wy, ww, partH + dist), QColor(220, 220, 210, 255), dist, unscaled, 256);

        wy += partH + d;
    }

    if (drawR) {
        drawComponentFull(&davinci, r, scaling, QRect(0, wy, ww, partH + dist), QColor(255, 128, 0, 255), dist, unscaled, 256);

        wy += partH + d;
    }

    if (drawG) {
        drawComponentFull(&davinci, g, scaling, QRect(0, wy, ww, partH + dist), QColor(128, 255, 0, 255), dist, unscaled, 256);
        wy += partH + d;
    }

    if (drawB) {
        drawComponentFull(&davinci, b, scaling, QRect(0, wy, ww, partH + dist), QColor(0, 128, 255, 255), dist, unscaled, 256);

        wy += partH + d;
    }

    return histogram;
}
示例#13
0
static bool write_jpeg_image(const QImage &image, QIODevice *device, int sourceQuality)
{
    bool success = false;
    const QVector<QRgb> cmap = image.colorTable();

    struct jpeg_compress_struct cinfo;
    JSAMPROW row_pointer[1];
    row_pointer[0] = 0;

    struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(device);
    struct my_error_mgr jerr;

    cinfo.err = jpeg_std_error(&jerr);
    jerr.error_exit = my_error_exit;

    if (!setjmp(jerr.setjmp_buffer)) {
        // WARNING:
        // this if loop is inside a setjmp/longjmp branch
        // do not create C++ temporaries here because the destructor may never be called
        // if you allocate memory, make sure that you can free it (row_pointer[0])
        jpeg_create_compress(&cinfo);

        cinfo.dest = iod_dest;

        cinfo.image_width = image.width();
        cinfo.image_height = image.height();

        bool gray=false;
        switch (image.format()) {
        case QImage::Format_Mono:
        case QImage::Format_MonoLSB:
        case QImage::Format_Indexed8:
            gray = true;
            for (int i = image.colorCount(); gray && i--;) {
                gray = gray & (qRed(cmap[i]) == qGreen(cmap[i]) &&
                               qRed(cmap[i]) == qBlue(cmap[i]));
            }
            cinfo.input_components = gray ? 1 : 3;
            cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
            break;
        default:
            cinfo.input_components = 3;
            cinfo.in_color_space = JCS_RGB;
        }

        jpeg_set_defaults(&cinfo);

        qreal diffInch = qAbs(image.dotsPerMeterX()*2.54/100. - qRound(image.dotsPerMeterX()*2.54/100.))
                         + qAbs(image.dotsPerMeterY()*2.54/100. - qRound(image.dotsPerMeterY()*2.54/100.));
        qreal diffCm = (qAbs(image.dotsPerMeterX()/100. - qRound(image.dotsPerMeterX()/100.))
                        + qAbs(image.dotsPerMeterY()/100. - qRound(image.dotsPerMeterY()/100.)))*2.54;
        if (diffInch < diffCm) {
            cinfo.density_unit = 1; // dots/inch
            cinfo.X_density = qRound(image.dotsPerMeterX()*2.54/100.);
            cinfo.Y_density = qRound(image.dotsPerMeterY()*2.54/100.);
        } else {
            cinfo.density_unit = 2; // dots/cm
            cinfo.X_density = (image.dotsPerMeterX()+50) / 100;
            cinfo.Y_density = (image.dotsPerMeterY()+50) / 100;
        }


        int quality = sourceQuality >= 0 ? qMin(sourceQuality,100) : 75;
#if defined(Q_OS_UNIXWARE)
        jpeg_set_quality(&cinfo, quality, B_TRUE /* limit to baseline-JPEG values */);
        jpeg_start_compress(&cinfo, B_TRUE);
#else
        jpeg_set_quality(&cinfo, quality, true /* limit to baseline-JPEG values */);
        jpeg_start_compress(&cinfo, true);
#endif

        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
        int w = cinfo.image_width;
        while (cinfo.next_scanline < cinfo.image_height) {
            uchar *row = row_pointer[0];
            switch (image.format()) {
            case QImage::Format_Mono:
            case QImage::Format_MonoLSB:
                if (gray) {
                    const uchar* data = image.constScanLine(cinfo.next_scanline);
                    if (image.format() == QImage::Format_MonoLSB) {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
                            row[i] = qRed(cmap[bit]);
                        }
                    } else {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
                            row[i] = qRed(cmap[bit]);
                        }
                    }
                } else {
                    const uchar* data = image.constScanLine(cinfo.next_scanline);
                    if (image.format() == QImage::Format_MonoLSB) {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
                            *row++ = qRed(cmap[bit]);
                            *row++ = qGreen(cmap[bit]);
                            *row++ = qBlue(cmap[bit]);
                        }
                    } else {
                        for (int i=0; i<w; i++) {
                            bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
                            *row++ = qRed(cmap[bit]);
                            *row++ = qGreen(cmap[bit]);
                            *row++ = qBlue(cmap[bit]);
                        }
                    }
                }
示例#14
0
void RGBMatrix::updateMapChannels(const RGBMap& map, const FixtureGroup* grp)
{
    uint fadeTime = (overrideFadeInSpeed() == defaultSpeed()) ? fadeInSpeed() : overrideFadeInSpeed();

    // Create/modify fade channels for ALL pixels in the color map.
    for (int y = 0; y < map.size(); y++)
    {
        for (int x = 0; x < map[y].size(); x++)
        {
            QLCPoint pt(x, y);
            GroupHead grpHead(grp->head(pt));
            Fixture* fxi = doc()->fixture(grpHead.fxi);
            if (fxi == NULL)
                continue;

            QLCFixtureHead head = fxi->head(grpHead.head);

            QVector <quint32> rgb = head.rgbChannels();
            QVector <quint32> cmy = head.cmyChannels();

            quint32 masterDim = fxi->masterIntensityChannel();
            quint32 headDim = head.channelNumber(QLCChannel::Intensity, QLCChannel::MSB);

            // Collect all dimmers that affect current head:
            // They are the master dimmer (affects whole fixture)
            // and per-head dimmer.
            //
            // If there are no RGB or CMY channels, the least important* dimmer channel
            // is used to create grayscale image.
            //
            // The rest of the dimmer channels are set to full if dimmer control is
            // enabled and target color is > 0 (see
            // http://www.qlcplus.org/forum/viewtopic.php?f=29&t=11090)
            //
            // Note: If there is only one head, and only one dimmer channel,
            // make it a master dimmer in fixture definition.
            //
            // *least important - per head dimmer if present,
            // otherwise per fixture dimmer if present
            QVector <quint32> dim;
            if (masterDim != QLCChannel::invalid())
                dim << masterDim;

            if (headDim != QLCChannel::invalid())
                dim << headDim;

            uint col = map[y][x];

            if (rgb.size() == 3)
            {
                // RGB color mixing
                {
                    FadeChannel fc(doc(), grpHead.fxi, rgb.at(0));
                    fc.setTarget(qRed(col));
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, rgb.at(1));
                    fc.setTarget(qGreen(col));
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, rgb.at(2));
                    fc.setTarget(qBlue(col));
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }
            }
            else if (cmy.size() == 3)
            {
                // CMY color mixing
                QColor cmyCol(col);

                {
                    FadeChannel fc(doc(), grpHead.fxi, cmy.at(0));
                    fc.setTarget(cmyCol.cyan());
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, cmy.at(1));
                    fc.setTarget(cmyCol.magenta());
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }

                {
                    FadeChannel fc(doc(), grpHead.fxi, cmy.at(2));
                    fc.setTarget(cmyCol.yellow());
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }
            }
            else if (!dim.empty())
            {
                // Set dimmer to value of the color (e.g. for PARs)
                FadeChannel fc(doc(), grpHead.fxi, dim.last());
                // the weights are taken from
                // https://en.wikipedia.org/wiki/YUV#SDTV_with_BT.601
                fc.setTarget(0.299 * qRed(col) + 0.587 * qGreen(col) + 0.114 * qBlue(col));
                insertStartValues(fc, fadeTime);
                m_fader->add(fc);
                dim.pop_back();
            }

            if (m_dimmerControl)
            {
                // Set the rest of the dimmer channels to full on
                foreach(quint32 ch, dim)
                {
                    FadeChannel fc(doc(), grpHead.fxi, ch);
                    fc.setTarget(col == 0 ? 0 : 255);
                    insertStartValues(fc, fadeTime);
                    m_fader->add(fc);
                }
            }
        }
    }
示例#15
0
// Flood fill
// ----- http://lodev.org/cgtutor/floodfill.html
void BitmapImage::floodFill(BitmapImage* targetImage,
                            QRect cameraRect,
                            QPoint point,
                            QRgb newColor,
                            int tolerance)
{
    // If the point we are supposed to fill is outside the image and camera bounds, do nothing
    if(!cameraRect.united(targetImage->bounds()).contains(point))
    {
        return;
    }

    // Square tolerance for use with compareColor
    tolerance = static_cast<int>(qPow(tolerance, 2));

    QRgb oldColor = targetImage->pixel(point);
    oldColor = qRgba(qRed(oldColor), qGreen(oldColor), qBlue(oldColor), qAlpha(oldColor));

    // Preparations
    QList<QPoint> queue; // queue all the pixels of the filled area (as they are found)

    BitmapImage* replaceImage = nullptr;
    QPoint tempPoint;
    QRgb newPlacedColor = 0;
    QScopedPointer< QHash<QRgb, bool> > cache(new QHash<QRgb, bool>());

    int xTemp = 0;
    bool spanLeft = false;
    bool spanRight = false;

    // Extend to size of Camera
    targetImage->extend(cameraRect);
    replaceImage = new BitmapImage(cameraRect, Qt::transparent);

    queue.append(point);
    // Preparations END

    while (!queue.empty())
    {
        tempPoint = queue.takeFirst();

        point.setX(tempPoint.x());
        point.setY(tempPoint.y());

        xTemp = point.x();

        newPlacedColor = replaceImage->constScanLine(xTemp, point.y());
        while (xTemp >= targetImage->mBounds.left() &&
               compareColor(targetImage->constScanLine(xTemp, point.y()), oldColor, tolerance, cache.data())) xTemp--;
        xTemp++;

        spanLeft = spanRight = false;
        while (xTemp <= targetImage->mBounds.right() &&
               compareColor(targetImage->constScanLine(xTemp, point.y()), oldColor, tolerance, cache.data()) &&
               newPlacedColor != newColor)
        {

            // Set pixel color
            replaceImage->scanLine(xTemp, point.y(), newColor);

            if (!spanLeft && (point.y() > targetImage->mBounds.top()) &&
                compareColor(targetImage->constScanLine(xTemp, point.y() - 1), oldColor, tolerance, cache.data())) {
                queue.append(QPoint(xTemp, point.y() - 1));
                spanLeft = true;
            }
            else if (spanLeft && (point.y() > targetImage->mBounds.top()) &&
                     !compareColor(targetImage->constScanLine(xTemp, point.y() - 1), oldColor, tolerance, cache.data())) {
                spanLeft = false;
            }

            if (!spanRight && point.y() < targetImage->mBounds.bottom() &&
                compareColor(targetImage->constScanLine(xTemp, point.y() + 1), oldColor, tolerance, cache.data())) {
                queue.append(QPoint(xTemp, point.y() + 1));
                spanRight = true;

            }
            else if (spanRight && point.y() < targetImage->mBounds.bottom() &&
                     !compareColor(targetImage->constScanLine(xTemp, point.y() + 1), oldColor, tolerance, cache.data())) {
                spanRight = false;
            }

            Q_ASSERT(queue.count() < (targetImage->mBounds.width() * targetImage->mBounds.height()));
            xTemp++;
        }
    }

    targetImage->paste(replaceImage);
    targetImage->modification();
    delete replaceImage;
}
示例#16
0
QImage EdgeDetection::gradientMagnitudeImage(QImage *image)
{
    QImage new_image(image->size(), QImage::Format_ARGB32_Premultiplied);
//    QImage orient_image(image->size(), QImage::Format_ARGB32_Premultiplied);

    QList<QPair<QPoint, QPair<int, int> > > x_y_struct;
    x_y_struct.append( qMakePair(QPoint(-1,-1), QPair<int,int>(-1, 1) ));
    x_y_struct.append( qMakePair(QPoint(-1,0), QPair<int,int>(-2, 0) ));
    x_y_struct.append( qMakePair(QPoint(-1,1), QPair<int,int>(-1,-1) ));
    x_y_struct.append( qMakePair(QPoint(0,-1), QPair<int,int>(0,2) ));
    x_y_struct.append( qMakePair(QPoint(0,0), QPair<int,int>(0,0) ));
    x_y_struct.append( qMakePair(QPoint(0,1), QPair<int,int>(0,-2) ));
    x_y_struct.append( qMakePair(QPoint(1,-1), QPair<int,int>(1,1) ));
    x_y_struct.append( qMakePair(QPoint(1,0), QPair<int,int>(2,0) ));
    x_y_struct.append( qMakePair(QPoint(1,1), QPair<int,int>(1, -1) ));

//    QList<QPair<QPoint, qreal> > orientations;
//    qreal orien_min = 1000;
//    qreal orien_max = 0;

//    int threshold = QInputDialog::getInteger(0, "Threshold", "Threshold value:", -1, -1, 255);

    for( int y=0; y < image->height(); y++ ) {
        for( int x=0; x < image->width(); x++ ) {
            QPoint point(x,y);
            int x_sum = 0;
            int x_rsum = 0;
            int x_gsum = 0;
            int x_bsum = 0;
            int y_sum = 0;
            int y_rsum = 0;
            int y_gsum = 0;
            int y_bsum = 0;
            //Perform Convolution on X
            for (int i=0; i < x_y_struct.size(); i++) {
                QPoint offset = x_y_struct.at(i).first;
                QPair<int,int> multiplier = x_y_struct.at(i).second;
                //Only convolve real pixels
                int pixel_x = offset.x() + x;
                int pixel_y = offset.y() + y;
                QRgb color;
                if ( pixel_x < 0 ||
                     pixel_x >= image->width() ||
                     pixel_y < 0 ||
                     pixel_y >= image->height() ) {
                    color = qRgb(128, 128, 128);
                } else {
                    color = image->pixel(QPoint(pixel_x, pixel_y));
                }

                int gray_val = qGray(color);
                x_sum += gray_val * multiplier.first;
                x_rsum += qRed(color) * multiplier.first;
                x_gsum += qGreen(color) * multiplier.first;
                x_bsum += qBlue(color) * multiplier.first;
                y_sum += gray_val * multiplier.second;
                y_rsum += qRed(color) * multiplier.second;
                y_gsum += qGreen(color) * multiplier.second;
                y_bsum += qBlue(color) * multiplier.second;
            }


            //Gradient
            qreal gradient = qSqrt(qPow(x_sum / 8, 2) + qPow(y_sum / 8, 2));
            qreal r_gradient = qSqrt(qPow(x_rsum / 8, 2) + qPow(y_rsum / 8, 2));
            qreal g_gradient = qSqrt(qPow(x_gsum / 8, 2) + qPow(y_gsum / 8, 2));
            qreal b_gradient = qSqrt(qPow(x_bsum / 8, 2) + qPow(y_bsum / 8, 2));

            //Orientation
//            qreal orientation = qAtan2(y_sum, x_sum);
//            if ( orientation < orien_min )
//                orien_min = orientation;

//            if ( orientation > orien_max )
//                orien_max = orientation;
//            orientations.append(qMakePair(point, orientation));

            //Threshold
//            QRgb val;
//            if ( threshold < 0 ) {
//                val = qRgb(gradient, gradient, gradient);
//            } else if ( gradient > threshold ) {
//                val = qRgb(255,255,255);
//            } else
//                val = qRgb(0,0,0);
//            new_image.setPixel(point, val);

            new_image.setPixel(point, qRgb(r_gradient, g_gradient, b_gradient));
        }
    }

//    for( int i=0; i < orientations.size(); i++ ) {
//        QPair<QPoint, qreal> o_pair = orientations.at(i);
//        qreal normal = Utility::rangeConvert(orien_max, orien_min, 255, 0, o_pair.second);
//        orient_image.setPixel(o_pair.first, qRgb(normal, normal, normal));
//    }


    return new_image;
}
示例#17
0
void MaskWidget::paintEvent(QPaintEvent* e)
{
	if (!m_desktopPixmap.isNull())
	{
		m_curPos = QCursor::pos();		
		QPainter painter(this);

		painter.drawPixmap(0, 0, m_desktopPixmap);

		if (!m_bScreenShotDone)
		{
			if (!m_bDragging)
			{
				m_curRc.setRect(-9999, -9999, 19999, 19999);
				for (std::vector<RECT>::iterator it = g_winRects.begin(); it != g_winRects.end(); ++it)
				{
					QRect rect;
					rect.setRect(it->left, it->top, it->right - it->left, it->bottom - it->top);
					if (rect.contains(QCursor::pos()) && m_curRc.contains(rect)/* && rect.height() > 5 && rect.width() > 5*/)
					{
						m_curRc = rect;
						//break;
					}
				}
			}
			else
			{
				m_curRc = QRect(m_startPoint, QCursor::pos());
			}
		}

		painter.save();
		painter.setPen(Qt::NoPen);
		painter.setBrush(QColor(0, 0, 0, 120));
		QPolygon p1(QRect(0, 0, width(), height()));
		QPolygon p2(m_curRc, true);
		p1 = p1.subtracted(p2);
		painter.drawPolygon(p1);
		painter.restore();

		painter.save();
		QPen pen = painter.pen();
		if (m_bScreenShotDone || m_bMousePressing)
		{
			pen.setWidth(2);
			pen.setColor(QColor(6, 157, 213));
			pen.setStyle(Qt::DashDotDotLine);
		}
		else
		{
			pen.setWidth(4);
			pen.setColor(QColor(0, 255, 0));
			pen.setStyle(Qt::SolidLine);
		}
		painter.setPen(pen);
		painter.drawRect(m_curRc);
		painter.restore();

		painter.save();
		
		QRect ori(m_curPos.x() - 15, m_curPos.y() - 11, 30, 22);
		QPixmap magnifier(126, 122);
		QPainter painter2(&magnifier);
		painter2.save();
		painter2.fillRect(0, 0, 126, 122, QBrush(QColor(51, 51, 51, 200)));
		painter2.restore();

		QPen p = painter2.pen();
		p.setWidth(1);
		p.setColor(QColor(51, 51, 51));
		painter2.setPen(p);
		painter2.drawRect(0, 0, 125, 93);

		p.setWidth(2);
		p.setColor(QColor(255, 255, 255));
		painter2.setPen(p);
		painter2.drawRect(2, 2, 122, 90);

		painter2.drawPixmap(3, 3, m_desktopPixmap.copy(ori).scaled(120, 88));

		p.setWidth(4);
		p.setColor(QColor(0, 122, 179, 128));
		painter2.setPen(p);
		painter2.drawLine(5, 45, 121, 45);
		painter2.drawLine(61, 5, 61, 89);

		p.setWidth(1);
		p.setColor(QColor(255, 255, 255));
		painter2.setPen(p);
		painter2.drawText(6, 105, QString("%1 x %2").arg(m_curRc.width()).arg(m_curRc.height()));
		QImage image = m_desktopPixmap.toImage();
		QRgb rgb = image.pixel(m_curPos.x()-1, m_curPos.y()-1);
		painter2.drawText(6, 118, QString("rgb(%1,%2,%3").arg(qRed(rgb)).arg(qGreen(rgb)).arg(qBlue(rgb)));

		QPoint showPoint(m_curPos.x() + 10, m_curPos.y() + 10);
		if (m_curPos.y() + 130 > this->height())
			showPoint.setY(m_curPos.y() - 130);

		if (m_curPos.x() + 130 > this->width())
			showPoint.setX(m_curPos.x() - 130);

		painter.drawPixmap(showPoint, magnifier);
	}
}
static void _soften(QString sourceFile, QString destFile)
{
    QImage image(sourceFile);
    if(image.isNull())
    {
        qDebug() << "load " << sourceFile << " failed! ";
        return;
    }
    int width = image.width();
    int height = image.height();
    int r, g, b;
    QRgb color;
    int xLimit = width - 1;
    int yLimit = height - 1;
    for(int i = 1; i < xLimit; i++)
    {
        for(int j = 1; j < yLimit; j++)
        {
            r = 0;
            g = 0;
            b = 0;
            for(int m = 0; m < 9; m++)
            {
                int s = 0;
                int p = 0;
                switch(m)
                {
                case 0:
                    s = i - 1;
                    p = j - 1;
                    break;
                case 1:
                    s = i;
                    p = j - 1;
                    break;
                case 2:
                    s = i + 1;
                    p = j - 1;
                    break;
                case 3:
                    s = i + 1;
                    p = j;
                    break;
                case 4:
                    s = i + 1;
                    p = j + 1;
                    break;
                case 5:
                    s = i;
                    p = j + 1;
                    break;
                case 6:
                    s = i - 1;
                    p = j + 1;
                    break;
                case 7:
                    s = i - 1;
                    p = j;
                    break;
                case 8:
                    s = i;
                    p = j;
                }
                color = image.pixel(s, p);
                r += qRed(color);
                g += qGreen(color);
                b += qBlue(color);
            }

            r = (int) (r / 9.0);
            g = (int) (g / 9.0);
            b = (int) (b / 9.0);

            r = qMin(255, qMax(0, r));
            g = qMin(255, qMax(0, g));
            b = qMin(255, qMax(0, b));

            image.setPixel(i, j, qRgb(r, g, b));
        }
    }

    image.save(destFile);
}
static QRgb weighpixel(QRgb rgb, int percentage)
{
    return qRgb((qRed(rgb) * percentage) >> (FIXEDPOINT_FRACTIONBITS * 2),
                (qGreen(rgb) * percentage) >> (FIXEDPOINT_FRACTIONBITS * 2),
                (qBlue(rgb) * percentage) >> (FIXEDPOINT_FRACTIONBITS * 2));
}
示例#20
0
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QDir src_dir("../gfx/");
    QDir dst_dir("c:/temp/");
    dst_dir.mkdir("gfx_2x/");
    dst_dir.cd("gfx_2x/");

    QRgb filter_rgb = qRgba(240, 0, 0, 255);
    QRgb mask_rgb = qRgba(255, 0, 255, 255);
    QRgb shadow_rgb = qRgba(127, 0, 127, 255);

    QStringList list = src_dir.entryList();
    foreach(const QString file, list) {
        qDebug("found file: %s", file.toStdString().c_str());
        QImage image(src_dir.filePath(file));
        if( !image.isNull() ) {
            if( image.width() % 2 != 0 ) {
                throw "image width not multiple of 2";
            }
            if( image.height() % 2 != 0 ) {
                throw "image height not multiple of 2";
            }
            int new_width = image.width() / 2;
            int new_height = image.height() / 2;
            QImage new_image(new_width, new_height, image.format());
            new_image.fill(0);
            for(int y=0;y<new_height;y++) {
                for(int x=0;x<new_width;x++) {
                    QRgb rgb00 = image.pixel(2*x, 2*y);
                    QRgb rgb10 = image.pixel(2*x+1, 2*y);
                    QRgb rgb01 = image.pixel(2*x, 2*y);
                    QRgb rgb11 = image.pixel(2*x+1, 2*y+1);
                    if( rgb00 == filter_rgb || rgb10 == filter_rgb || rgb01 == filter_rgb || rgb11 == filter_rgb ) {
                        rgb00 = filter_rgb;
                        rgb10 = filter_rgb;
                        rgb01 = filter_rgb;
                        rgb11 = filter_rgb;
                    }
                    else if( rgb00 == mask_rgb || rgb10 == mask_rgb || rgb01 == mask_rgb || rgb11 == mask_rgb ) {
                        rgb00 = mask_rgb;
                        rgb10 = mask_rgb;
                        rgb01 = mask_rgb;
                        rgb11 = mask_rgb;
                    }
                    else if( rgb00 == shadow_rgb || rgb10 == shadow_rgb || rgb01 == shadow_rgb || rgb11 == shadow_rgb ) {
                        rgb00 = shadow_rgb;
                        rgb10 = shadow_rgb;
                        rgb01 = shadow_rgb;
                        rgb11 = shadow_rgb;
                    }
                    /*if( rgb00 == mask_rgb ) {
                        rgb00 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb10 == mask_rgb ) {
                        rgb10 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb01 == mask_rgb ) {
                        rgb01 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb11 == mask_rgb ) {
                        rgb11 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb00 == shadow_rgb ) {
                        rgb00 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb10 == shadow_rgb ) {
                        rgb10 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb01 == shadow_rgb ) {
                        rgb01 = qRgba(0, 0, 0, 0);
                    }
                    if( rgb11 == shadow_rgb ) {
                        rgb11 = qRgba(0, 0, 0, 0);
                    }*/
                    int irgb00[] = {qRed(rgb00), qGreen(rgb00), qBlue(rgb00), qAlpha(rgb00)};
                    int irgb10[] = {qRed(rgb10), qGreen(rgb10), qBlue(rgb10), qAlpha(rgb10)};
                    int irgb01[] = {qRed(rgb01), qGreen(rgb01), qBlue(rgb01), qAlpha(rgb01)};
                    int irgb11[] = {qRed(rgb11), qGreen(rgb11), qBlue(rgb11), qAlpha(rgb11)};
                    int irgb[] = {0, 0, 0, 0};
                    for(int i=0;i<4;i++) {
                        int result = (int)((irgb00[i] + irgb10[i] + irgb01[i] + irgb11[i]) / 4.0);
                        irgb[i] = result;
                    }
                    QRgb rgb = qRgba(irgb[0], irgb[1], irgb[2], irgb[3]);
                    new_image.setPixel(x, y, rgb);
                }
            }
            QString save_filename = dst_dir.filePath(file);
            qDebug("    save as %s", save_filename.toStdString().c_str());
            if( !new_image.save(save_filename) ) {
                throw "failed to save";
            }
        }
        else {
            qDebug("    failed to load");
        }
    }
示例#21
0
文件: main.cpp 项目: joetde/2048bot
bool closeRGB(const QRgb &r1, const QRgb &r2)
{
    return std::abs(qRed(r1) - qRed(r2)) +
           std::abs(qGreen(r1) - qGreen(r2)) +
           std::abs(qBlue(r1) - qBlue(r2)) < ColorThreshold;
}
示例#22
0
QgsRasterFileWriter::WriterError QgsRasterFileWriter::writeImageRaster( QgsRasterIterator* iter, int nCols, int nRows, const QgsRectangle& outputExtent,
    const QgsCoordinateReferenceSystem& crs, QProgressDialog* progressDialog )
{
  QgsDebugMsg( "Entered" );
  if ( !iter )
  {
    return SourceProviderError;
  }

  const QgsRasterInterface* iface = iter->input();
  QGis::DataType inputDataType = iface->dataType( 1 );
  if ( !iface || ( inputDataType != QGis::ARGB32 &&
                   inputDataType != QGis::ARGB32_Premultiplied ) )
  {
    return SourceProviderError;
  }

  iter->setMaximumTileWidth( mMaxTileWidth );
  iter->setMaximumTileHeight( mMaxTileHeight );

  void* redData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  void* greenData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  void* blueData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  void* alphaData = qgsMalloc( mMaxTileWidth * mMaxTileHeight );
  QgsRectangle mapRect;
  int iterLeft = 0, iterTop = 0, iterCols = 0, iterRows = 0;
  int fileIndex = 0;

  //create destProvider for whole dataset here
  QgsRasterDataProvider* destProvider = 0;
  double pixelSize;
  double geoTransform[6];
  globalOutputParameters( outputExtent, nCols, nRows, geoTransform, pixelSize );

  destProvider = initOutput( nCols, nRows, crs, geoTransform, 4, QGis::Byte );

  iter->startRasterRead( 1, nCols, nRows, outputExtent );

  int nParts = 0;
  if ( progressDialog )
  {
    int nPartsX = nCols / iter->maximumTileWidth() + 1;
    int nPartsY = nRows / iter->maximumTileHeight() + 1;
    nParts = nPartsX * nPartsY;
    progressDialog->setMaximum( nParts );
    progressDialog->show();
    progressDialog->setLabelText( QObject::tr( "Reading raster part %1 of %2" ).arg( fileIndex + 1 ).arg( nParts ) );
  }

  QgsRasterBlock *inputBlock = 0;
  while ( iter->readNextRasterPart( 1, iterCols, iterRows, &inputBlock, iterLeft, iterTop ) )
  {
    if ( !inputBlock )
    {
      continue;
    }

    if ( progressDialog && fileIndex < ( nParts - 1 ) )
    {
      progressDialog->setValue( fileIndex + 1 );
      progressDialog->setLabelText( QObject::tr( "Reading raster part %1 of %2" ).arg( fileIndex + 2 ).arg( nParts ) );
      QCoreApplication::processEvents( QEventLoop::AllEvents, 1000 );
      if ( progressDialog->wasCanceled() )
      {
        delete inputBlock;
        break;
      }
    }

    //fill into red/green/blue/alpha channels
    qgssize nPixels = ( qgssize )iterCols * iterRows;
    // TODO: should be char not int? we are then copying 1 byte
    int red = 0;
    int green = 0;
    int blue = 0;
    int alpha = 255;
    for ( qgssize i = 0; i < nPixels; ++i )
    {
      QRgb c = inputBlock->color( i );
      alpha = qAlpha( c );
      red = qRed( c ); green = qGreen( c ); blue = qBlue( c );

      if ( inputDataType == QGis::ARGB32_Premultiplied )
      {
        double a = alpha / 255.;
        QgsDebugMsgLevel( QString( "red = %1 green = %2 blue = %3 alpha = %4 p = %5 a = %6" ).arg( red ).arg( green ).arg( blue ).arg( alpha ).arg(( int )c, 0, 16 ).arg( a ), 5 );
        red /= a;
        green /= a;
        blue /= a;
      }
      memcpy(( char* )redData + i, &red, 1 );
      memcpy(( char* )greenData + i, &green, 1 );
      memcpy(( char* )blueData + i, &blue, 1 );
      memcpy(( char* )alphaData + i, &alpha, 1 );
    }
    delete inputBlock;

    //create output file
    if ( mTiledMode )
    {
      //delete destProvider;
      QgsRasterDataProvider* partDestProvider = createPartProvider( outputExtent,
          nCols, iterCols, iterRows,
          iterLeft, iterTop, mOutputUrl, fileIndex,
          4, QGis::Byte, crs );

      if ( partDestProvider )
      {
        //write data to output file
        partDestProvider->write( redData, 1, iterCols, iterRows, 0, 0 );
        partDestProvider->write( greenData, 2, iterCols, iterRows, 0, 0 );
        partDestProvider->write( blueData, 3, iterCols, iterRows, 0, 0 );
        partDestProvider->write( alphaData, 4, iterCols, iterRows, 0, 0 );

        addToVRT( partFileName( fileIndex ), 1, iterCols, iterRows, iterLeft, iterTop );
        addToVRT( partFileName( fileIndex ), 2, iterCols, iterRows, iterLeft, iterTop );
        addToVRT( partFileName( fileIndex ), 3, iterCols, iterRows, iterLeft, iterTop );
        addToVRT( partFileName( fileIndex ), 4, iterCols, iterRows, iterLeft, iterTop );
        delete partDestProvider;
      }
    }
    else if ( destProvider )
    {
      destProvider->write( redData, 1, iterCols, iterRows, iterLeft, iterTop );
      destProvider->write( greenData, 2, iterCols, iterRows, iterLeft, iterTop );
      destProvider->write( blueData, 3, iterCols, iterRows, iterLeft, iterTop );
      destProvider->write( alphaData, 4, iterCols, iterRows, iterLeft, iterTop );
    }

    ++fileIndex;
  }

  if ( destProvider )
    delete destProvider;

  qgsFree( redData ); qgsFree( greenData ); qgsFree( blueData ); qgsFree( alphaData );

  if ( progressDialog )
  {
    progressDialog->setValue( progressDialog->maximum() );
  }

  if ( mTiledMode )
  {
    QString vrtFilePath( mOutputUrl + "/" + vrtFileName() );
    writeVRT( vrtFilePath );
    if ( mBuildPyramidsFlag == QgsRaster::PyramidsFlagYes )
    {
      buildPyramids( vrtFilePath );
    }
  }
  else
  {
    if ( mBuildPyramidsFlag == QgsRaster::PyramidsFlagYes )
    {
      buildPyramids( mOutputUrl );
    }
  }
  return NoError;
}
示例#23
0
bool Q_INTERNAL_WIN_NO_THROW QPNGImageWriter::writeImage(const QImage& image, volatile int quality_in, const QString &description,
                                 int off_x_in, int off_y_in)
{
    QPoint offset = image.offset();
    int off_x = off_x_in + offset.x();
    int off_y = off_y_in + offset.y();

    png_structp png_ptr;
    png_infop info_ptr;

    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
    if (!png_ptr) {
        return false;
    }

    png_set_error_fn(png_ptr, 0, 0, qt_png_warning);

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        png_destroy_write_struct(&png_ptr, 0);
        return false;
    }

    if (setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_write_struct(&png_ptr, &info_ptr);
        return false;
    }

    int quality = quality_in;
    if (quality >= 0) {
        if (quality > 9) {
            qWarning("PNG: Quality %d out of range", quality);
            quality = 9;
        }
        png_set_compression_level(png_ptr, quality);
    }

    png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);


    int color_type = 0;
    if (image.colorCount()) {
        if (image.isGrayscale())
            color_type = PNG_COLOR_TYPE_GRAY;
        else
            color_type = PNG_COLOR_TYPE_PALETTE;
    }
    else if (image.format() == QImage::Format_Grayscale8)
        color_type = PNG_COLOR_TYPE_GRAY;
    else if (image.hasAlphaChannel())
        color_type = PNG_COLOR_TYPE_RGB_ALPHA;
    else
        color_type = PNG_COLOR_TYPE_RGB;

    png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
                 image.depth() == 1 ? 1 : 8, // per channel
                 color_type, 0, 0, 0);       // sets #channels

    if (gamma != 0.0) {
        png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);
    }

    if (image.format() == QImage::Format_MonoLSB)
       png_set_packswap(png_ptr);

    if (color_type == PNG_COLOR_TYPE_PALETTE) {
        // Paletted
        int num_palette = qMin(256, image.colorCount());
        png_color palette[256];
        png_byte trans[256];
        int num_trans = 0;
        for (int i=0; i<num_palette; i++) {
            QRgb rgba=image.color(i);
            palette[i].red = qRed(rgba);
            palette[i].green = qGreen(rgba);
            palette[i].blue = qBlue(rgba);
            trans[i] = qAlpha(rgba);
            if (trans[i] < 255) {
                num_trans = i+1;
            }
        }
        png_set_PLTE(png_ptr, info_ptr, palette, num_palette);

        if (num_trans) {
            png_set_tRNS(png_ptr, info_ptr, trans, num_trans, 0);
        }
    }

    // Swap ARGB to RGBA (normal PNG format) before saving on
    // BigEndian machines
    if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
        png_set_swap_alpha(png_ptr);
    }

    // Qt==ARGB==Big(ARGB)==Little(BGRA). But RGB888 is RGB regardless
    if (QSysInfo::ByteOrder == QSysInfo::LittleEndian
        && image.format() != QImage::Format_RGB888) {
        png_set_bgr(png_ptr);
    }

    if (off_x || off_y) {
        png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL);
    }

    if (frames_written > 0)
        png_set_sig_bytes(png_ptr, 8);

    if (image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0) {
        png_set_pHYs(png_ptr, info_ptr,
                image.dotsPerMeterX(), image.dotsPerMeterY(),
                PNG_RESOLUTION_METER);
    }

    set_text(image, png_ptr, info_ptr, description);

    png_write_info(png_ptr, info_ptr);

    if (image.depth() != 1)
        png_set_packing(png_ptr);

    if (color_type == PNG_COLOR_TYPE_RGB && image.format() != QImage::Format_RGB888)
        png_set_filler(png_ptr, 0,
            QSysInfo::ByteOrder == QSysInfo::BigEndian ?
                PNG_FILLER_BEFORE : PNG_FILLER_AFTER);

    if (looping >= 0 && frames_written == 0) {
        uchar data[13] = "NETSCAPE2.0";
        //                0123456789aBC
        data[0xB] = looping%0x100;
        data[0xC] = looping/0x100;
        png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFx"), data, 13);
    }
    if (ms_delay >= 0 || disposal!=Unspecified) {
        uchar data[4];
        data[0] = disposal;
        data[1] = 0;
        data[2] = (ms_delay/10)/0x100; // hundredths
        data[3] = (ms_delay/10)%0x100;
        png_write_chunk(png_ptr, const_cast<png_bytep>((const png_byte *)"gIFg"), data, 4);
    }

    int height = image.height();
    int width = image.width();
    switch (image.format()) {
    case QImage::Format_Mono:
    case QImage::Format_MonoLSB:
    case QImage::Format_Indexed8:
    case QImage::Format_Grayscale8:
    case QImage::Format_RGB32:
    case QImage::Format_ARGB32:
    case QImage::Format_RGB888:
        {
            png_bytep* row_pointers = new png_bytep[height];
            for (int y=0; y<height; y++)
                row_pointers[y] = const_cast<png_bytep>(image.constScanLine(y));
            png_write_image(png_ptr, row_pointers);
            delete [] row_pointers;
        }
        break;
    default:
        {
            QImage::Format fmt = image.hasAlphaChannel() ? QImage::Format_ARGB32 : QImage::Format_RGB32;
            QImage row;
            png_bytep row_pointers[1];
            for (int y=0; y<height; y++) {
                row = image.copy(0, y, width, 1).convertToFormat(fmt);
                row_pointers[0] = const_cast<png_bytep>(row.constScanLine(0));
                png_write_rows(png_ptr, row_pointers, 1);
            }
        }
        break;
    }

    png_write_end(png_ptr, info_ptr);
    frames_written++;

    png_destroy_write_struct(&png_ptr, &info_ptr);

    return true;
}
示例#24
0
QRgb macGetRgba( QRgb initial, bool *ok, QWidget *parent, const char* )
{
    Point p = { -1, -1 };
    const uchar *pstr = p_str("Choose a color");
    static const int sw = 420, sh = 300;
    if(parent) {
	parent = parent->topLevelWidget();
	p.h = (parent->x() + (parent->width() / 2)) - (sw / 2);
	p.v = (parent->y() + (parent->height() / 2)) - (sh / 2);
	QRect r = QApplication::desktop()->screenGeometry(QApplication::desktop()->screenNumber(parent));
	if(p.h + sw > r.right())
	    p.h -= (p.h + sw) - r.right() + 10;
	if(p.v + sh > r.bottom())
	    p.v -= (p.v + sh) - r.bottom() + 10;
    } else if(QWidget *w = qApp->mainWidget()) {
	static int last_screen = -1;
	int scr = QApplication::desktop()->screenNumber(w);
	if(last_screen != scr) {
	    QRect r = QApplication::desktop()->screenGeometry(scr);
	    p.h = (r.x() + (r.width() / 2)) - (sw / 2);
	    p.v = (r.y() + (r.height() / 2)) - (sh / 2);
	}
    }
    RGBColor rgb, rgbout;
    rgb.red = qRed(initial) * 256;
    rgb.blue = qBlue(initial) * 256;
    rgb.green = qGreen(initial) * 256;
#if 1
    Point place;
    place.h = p.h == -1 ? 0 : p.h;
    place.v = p.v == -1 ? 0 : p.v;
    Boolean rval = FALSE;
    {
	QMacBlockingFunction block;
	QWidget modal_widg(parent, __FILE__ "__modal_dlg",
			   Qt::WType_TopLevel | Qt::WStyle_Customize | Qt::WStyle_DialogBorder);
	qt_enter_modal(&modal_widg);
	rval = GetColor(place, pstr, &rgb, &rgbout);
	qt_leave_modal(&modal_widg);
    }
#else
    ColorPickerInfo     cpInfo;
    // Set the input color to be an RGB color in system space.
    cpInfo.theColor.color.rgb.red = rgb.red;
    cpInfo.theColor.color.rgb.green = rgb.green;
    cpInfo.theColor.color.rgb.blue = rgb.blue;
    cpInfo.theColor.profile = 0L;
    cpInfo.dstProfile = 0L;
    cpInfo.flags = kColorPickerAppIsColorSyncAware | kColorPickerCanModifyPalette |
		   kColorPickerCanAnimatePalette;
    // Place dialog
    cpInfo.placeWhere = kCenterOnMainScreen;
    if(p.h != -1 || p.v != -1) {
	cpInfo.placeWhere = kAtSpecifiedOrigin;
	cpInfo.dialogOrigin = p;
    }
    cpInfo.pickerType = 0L; // Use the default picker.
    cpInfo.eventProc = 0L;
    cpInfo.colorProc = 0L;
    cpInfo.colorProcData = 0L;
    memcpy(cpInfo.prompt, pstr, pstr[0]+1);
    Boolean rval = FALSE;
    {
	QMacBlockingFunction block;
	rval = (PickColor(&cpInfo) == noErr && cpInfo.newColorChosen);
    }
    if(rval) {
	rval = TRUE;
	if(!cpInfo.theColor.profile) {
	    rgbout.red = cpInfo.theColor.color.rgb.red;
	    rgbout.green = cpInfo.theColor.color.rgb.green;
	    rgbout.blue = cpInfo.theColor.color.rgb.blue;
	} else {
	    qDebug("not sure how to handle..");
	}
    }
#endif
    free((void *)pstr);
    if(ok)
	(*ok) = rval;
    if(!rval)
	return initial;
    initial = qRgba(rgbout.red / 256, rgbout.green / 256,
		    rgbout.blue / 256, qAlpha(initial));
    return initial;
}
示例#25
0
bool QgsHttpRequestHandler::minMaxRange( const QgsColorBox& colorBox, int& redRange, int& greenRange, int& blueRange, int& alphaRange )
{
  if ( colorBox.size() < 1 )
  {
    return false;
  }

  int rMin = INT_MAX;
  int gMin = INT_MAX;
  int bMin = INT_MAX;
  int aMin = INT_MAX;
  int rMax = INT_MIN;
  int gMax = INT_MIN;
  int bMax = INT_MIN;
  int aMax = INT_MIN;

  int currentRed = 0;
  int currentGreen = 0;
  int currentBlue = 0;
  int currentAlpha = 0;

  QgsColorBox::const_iterator colorBoxIt = colorBox.constBegin();
  for ( ; colorBoxIt != colorBox.constEnd(); ++colorBoxIt )
  {
    currentRed = qRed( colorBoxIt->first );
    if ( currentRed > rMax )
    {
      rMax = currentRed;
    }
    if ( currentRed < rMin )
    {
      rMin = currentRed;
    }

    currentGreen = qGreen( colorBoxIt->first );
    if ( currentGreen > gMax )
    {
      gMax = currentGreen;
    }
    if ( currentGreen < gMin )
    {
      gMin = currentGreen;
    }

    currentBlue = qBlue( colorBoxIt->first );
    if ( currentBlue > bMax )
    {
      bMax = currentBlue;
    }
    if ( currentBlue < bMin )
    {
      bMin = currentBlue;
    }

    currentAlpha = qAlpha( colorBoxIt->first );
    if ( currentAlpha > aMax )
    {
      aMax = currentAlpha;
    }
    if ( currentAlpha < aMin )
    {
      aMin = currentAlpha;
    }
  }

  redRange = rMax - rMin;
  greenRange = gMax - gMin;
  blueRange = bMax - bMin;
  alphaRange = aMax - aMin;
  return true;
}
示例#26
0
QImage CompositeEffect::processImages(const QVector<QImage> &images, const KoFilterEffectRenderContext &context) const
{
    int imageCount = images.count();
    if (!imageCount)
        return QImage();

    QImage result = images[0];
    if (images.count() != 2) {
        return result;
    }

    if (m_operation == Arithmetic) {
        const QRgb *src = (QRgb*)images[1].constBits();
        QRgb *dst = (QRgb*)result.bits();
        int w = result.width();

        qreal sa, sr, sg, sb;
        qreal da, dr, dg, db;
        int pixel = 0;

        // TODO: do we have to calculate with non-premuliplied colors here ???

        QRect roi = context.filterRegion().toRect();
        for (int row = roi.top(); row < roi.bottom(); ++row) {
            for (int col = roi.left(); col < roi.right(); ++col) {
                pixel = row * w + col;
                const QRgb &s = src[pixel];
                QRgb &d = dst[pixel];

                sa = fromIntColor[qAlpha(s)];
                sr = fromIntColor[qRed(s)];
                sg = fromIntColor[qGreen(s)];
                sb = fromIntColor[qBlue(s)];

                da = fromIntColor[qAlpha(d)];
                dr = fromIntColor[qRed(d)];
                dg = fromIntColor[qGreen(d)];
                db = fromIntColor[qBlue(d)];

                da = m_k[0] * sa * da + m_k[1] * da + m_k[2] * sa + m_k[3];
                dr = m_k[0] * sr * dr + m_k[1] * dr + m_k[2] * sr + m_k[3];
                dg = m_k[0] * sg * dg + m_k[1] * dg + m_k[2] * sg + m_k[3];
                db = m_k[0] * sb * db + m_k[1] * db + m_k[2] * sb + m_k[3];

                da *= 255.0;

                // set pre-multiplied color values on destination image
                d = qRgba(static_cast<quint8>(qBound(qreal(0.0), dr * da, qreal(255.0))),
                          static_cast<quint8>(qBound(qreal(0.0), dg * da, qreal(255.0))),
                          static_cast<quint8>(qBound(qreal(0.0), db * da, qreal(255.0))),
                          static_cast<quint8>(qBound(qreal(0.0), da, qreal(255.0))));
            }
        }
    } else {
        QPainter painter(&result);

        switch (m_operation) {
        case CompositeOver:
            painter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
            break;
        case CompositeIn:
            painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
            break;
        case CompositeOut:
            painter.setCompositionMode(QPainter::CompositionMode_DestinationOut);
            break;
        case CompositeAtop:
            painter.setCompositionMode(QPainter::CompositionMode_DestinationAtop);
            break;
        case CompositeXor:
            painter.setCompositionMode(QPainter::CompositionMode_Xor);
            break;
        default:
            // no composition mode
            break;
        }
        painter.drawImage(context.filterRegion(), images[1], context.filterRegion());
    }

    return result;
}
示例#27
0
//===========================================================================//
// void ImageOperations::subsample(QImage image, QImage* ret,                //
//                                 bool resize = true)                       //
//===========================================================================//
// INPUTS:    image: QImage to be sub-sampled by factor 2.                   //
//            resize: flag to indicate whether the size of the image should  //
//                    be decreased by factor 2 as part of sub-sampling or    //
//                    pixel values duplicated to maintain the original size. //
// OUTPUTS:   QImage: Sub-sampled image of either equal or half the original //
//                    size.                                                  //
// OPERATION: The average of a pixel and its right, lower and lower-right    //
//            neighbours is computed and used as value for the pixel(s) in   //
//            the sub-sampled image.                                         //
//===========================================================================//
void ImageOperations::subsample( const QImage& qimg, QImage& qimgRet,
                                 bool bResize)
{
  int subs_w, subs_h;
  if( bResize )
  {                                          // Compute the
    subs_w = int(qimg.width()/2);                          //  size of the
    subs_h = int(qimg.height()/2);                         //  output image.

  }
  else
  {
    subs_w = qimg.width();
    subs_h = qimg.height();
  }
  qimgRet.create(subs_w, subs_h, 32);

  int col_r, col_g, col_b;
  for (int y=0; y<qimg.height(); y+=2)
  {                  // Traverse image
    for (int x=0; x<qimg.width(); x+=2)
    {                 //  and compute
      col_r = qRed(qimg.pixel(x,y));                      //  average of
      col_g = qGreen(qimg.pixel(x,y));                    //  the pixel and
      col_b = qBlue(qimg.pixel(x,y));                     //  its neighbours
      int sum = 1;                                        //  to the right,
      if (x < qimg.width()-1)
      {                           //  the bottom as
        col_r += qRed  (qimg.pixel(x+1, y));              //  well as the
        col_g += qGreen(qimg.pixel(x+1,y));               //  bottom-right.
        col_b += qBlue (qimg.pixel(x+1,y));               //  Consider image
        sum++;                                            //  borders.
      }

      if (y < qimg.height()-1)
      {
        col_r += qRed  (qimg.pixel(x,y+1));
        col_g += qGreen(qimg.pixel(x,y+1));
        col_b += qBlue (qimg.pixel(x,y+1));
        sum++;
      }

      if ((x<qimg.width()-1) && (y<qimg.height()-1))
      {
        col_r += qRed  (qimg.pixel(x+1, y+1));
        col_g += qGreen(qimg.pixel(x+1, y+1));
        col_b += qBlue (qimg.pixel(x+1, y+1));
        sum++;
      }
      col_r /= sum;
      col_g /= sum;
      col_b /= sum;
      if (bResize)
      {                                       // Set the output
        if ((int(x/2) < subs_w) && (int(y/2) < subs_h))
        {  //  image's pixels
          qimgRet.setPixel(int(x/2), int(y/2),             //  to the computed
                           qRgb(col_r, col_g, col_b));     //  values.
        }

      }
      else
      {                                             // In the case that
        qimgRet.setPixel(x,   y,   qRgb(col_r, col_g,      //  the image is
                                        col_b));           //  not being re-
        if (x < qimg.width()-1)
        {                          //  sized, four
          qimgRet.setPixel(x+1, y,   qRgb(col_r, col_g,    //  pixels hold
                                          col_b));         //  the same value
        }                                                  //  (with the
        if (y < qimg.height()-1)
        {                         //  exception of
          qimgRet.setPixel(x,   y+1, qRgb(col_r, col_g,    //  the borders).
                                          col_b));
        }
        if ((x<qimg.width()-1) && (y<qimg.height()-1))
        {
          qimgRet.setPixel(x+1, y+1, qRgb(col_r, col_g,
                                          col_b));
        }
      }
    }
  }
}
示例#28
0
  void MeshRenderer :: renderToImage(cv::Mat4b& image, int flags)
  {
    ntk_assert(m_vertex_buffer_object.initialized,
               "Renderer not initialized! Call setPose and setMesh.");

    ntk::TimeCount tc_gl_current("make_current", 2);
    m_pbuffer->makeCurrent();
    tc_gl_current.stop();

    ntk::TimeCount tc_gl_render("gl_render", 2);

    if (flags & WIREFRAME)
      glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

    VertexBufferObject& vbo = m_vertex_buffer_object;
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo.vertex_id);

    if (vbo.has_texcoords)
    {
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, vbo.texture_id);
    }
    else
    {
      glDisable(GL_TEXTURE_2D);
    }

    if (vbo.has_texcoords)
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    if (vbo.has_color)
      glEnableClientState(GL_COLOR_ARRAY);
    else
      glColor3f(1.0f,0.f,0.f);

    glEnableClientState(GL_VERTEX_ARRAY);

    glVertexPointer(3, GL_FLOAT, 0, 0);
    if (vbo.has_color)
      glColorPointer(3, GL_UNSIGNED_BYTE, 0, ((char*) NULL) + vbo.color_offset);

    if (vbo.has_texcoords)
      glTexCoordPointer(2, GL_FLOAT, 0, ((char*) NULL) + vbo.texture_offset);

    if (vbo.has_faces)
    {
      glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbo.faces_id);
      glNormal3f(0, 0, 1);
      glDrawElements(GL_TRIANGLES, vbo.nb_faces*3, GL_UNSIGNED_INT, 0);
    }
    else
    {
      glDrawArrays(GL_POINTS,
                   0,
                   vbo.nb_vertices);
    }

    glDisableClientState(GL_VERTEX_ARRAY);

    if (vbo.has_color)
      glDisableClientState(GL_COLOR_ARRAY);

    if (vbo.has_texcoords)
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    // bind with 0, so, switch back to normal pointer operation
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

    if (vbo.has_faces)
    {
      glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
    }

    glFinish();
    tc_gl_render.stop();

    ntk::TimeCount tc_image("to_image", 2);
    QImage qimage = m_pbuffer->toImage();
    tc_image.stop();

    ntk::TimeCount tc_depth_buffer("compute_depth_buffer", 2);
    computeDepthBuffer();
    tc_depth_buffer.stop();

    ntk::TimeCount tc_convert("convert_to_cv", 2);
    for (int r = 0; r < qimage.height(); ++r)
      for (int c = 0; c < qimage.width(); ++c)
      {
      QRgb pixel = qimage.pixel(c,r);
      Vec4b color (qBlue(pixel), qGreen(pixel), qRed(pixel), qAlpha(pixel));
      m_color_buffer(r,c) = color;
      float a = qAlpha(pixel)/255.f;
      if (a > 0)
      {
        Vec4b old_color = image(r,c);
        image(r,c) = Vec4b(old_color[0]*(1-a) + color[0]*a,
                           old_color[1]*(1-a) + color[1]*a,
                           old_color[2]*(1-a) + color[2]*a,
                           255);
      }
    }    
    tc_convert.stop();
  }
示例#29
0
void ImageOperations::colorCanny( const OpRGBImage& img,
                                  OpGrayImage& imgRet,
                                  float dThreshLow, float dThreshHigh,
                                  float dSigma )
{
  //printf("ImageOperations::colorCanny() ...\n");
  QImage qimg = img.getQtImage();

  int w = qimg.width();
  int h = qimg.height();

  //- create a YCC color-opponent image from the input image -//
  OpGrayImage imgY ( w, h );
  OpGrayImage imgC1( w, h );
  OpGrayImage imgC2( w, h );

  for (int y=0; y < h; y++)
  {
    for (int x=0; x < w; x++)
    {
      // img is the original QImage //
      uint *p = (uint *) qimg.scanLine(y) + x;

      //-- convert rgb to YCC --//
      imgY(x,y)  = (1.0/3.0)*(qRed(*p) + qGreen(*p) + qBlue(*p));
      imgC1(x,y) = 2.0*(0.5*qRed(*p) - 0.5*qGreen(*p));
      imgC2(x,y) = 2.0*(0.5*qRed(*p) + 0.5*qGreen(*p) - qBlue(*p));
    }
  }
  //-- apply the filter --//
  OpGrayImage imgDx( w, h );
  OpGrayImage imgDy( w, h );

  //-- fast gauss --//
  OpGrayImage imgYDx( w, h );
  OpGrayImage imgYDy( w, h );
  imgY.opFastGaussDxDy( dSigma, imgYDx, imgYDy );

  OpGrayImage imgC1Dx( w, h );
  OpGrayImage imgC1Dy( w, h );
  imgC1.opFastGaussDxDy( dSigma, imgC1Dx, imgC1Dy );

  OpGrayImage imgC2Dx( w, h );
  OpGrayImage imgC2Dy( w, h );
  imgC2.opFastGaussDxDy( dSigma, imgC2Dx, imgC2Dy );

  for (int y=0; y < h; y++)
  {
    for (int x=0; x < w; x++)
    {
      imgDx(x,y) = sqrt( imgYDx(x,y).value()*imgYDx(x,y).value() +
                         imgC1Dx(x,y).value()*imgC1Dx(x,y).value() +
                         imgC2Dx(x,y).value()*imgC2Dx(x,y).value() );
      imgDy(x,y) = sqrt( imgYDy(x,y).value()*imgYDy(x,y).value() +
                         imgC1Dy(x,y).value()*imgC1Dy(x,y).value() +
                         imgC2Dy(x,y).value()*imgC2Dy(x,y).value() );
    }
  }
  /*
  //-- slow gauss --//    
  OpGrayImage imgYDx  = imgY.opGaussDerivGx( m_dSigma );
  OpGrayImage imgYDy  = imgY.opGaussDerivGy( m_dSigma );
  OpGrayImage imgC1Dx = imgC1.opGaussDerivGx( m_dSigma );
  OpGrayImage imgC1Dy = imgC1.opGaussDerivGy( m_dSigma );
  OpGrayImage imgC2Dx = imgC2.opGaussDerivGx( m_dSigma );
  OpGrayImage imgC2Dy = imgC2.opGaussDerivGy( m_dSigma );

  for (int y=0; y < m_img.height(); y++)
  for (int x=0; x < m_img.width(); x++)
  {
  imgDx(x,y) = sqrt( imgYDx(x,y).value()*imgYDx(x,y).value() +
  imgC1Dx(x,y).value()*imgC1Dx(x,y).value() +
  imgC2Dx(x,y).value()*imgC2Dx(x,y).value() );
  imgDy(x,y) = sqrt( imgYDy(x,y).value()*imgYDy(x,y).value() +
  imgC1Dy(x,y).value()*imgC1Dy(x,y).value() +
  imgC2Dy(x,y).value()*imgC2Dy(x,y).value() );
  }
  */

  //-- apply the Canny operator --//
  OpGrayImage resultImg( w, h );
  imgRet = resultImg;
  imgRet = cannyEdgesDxDy( imgDx, imgDy, dThreshLow, dThreshHigh );
}
示例#30
0
ccPointCloud* ccCalibratedImage::orthoRectifyAsCloud(CCLib::GenericIndexedCloud* keypoints3D, std::vector<KeyPoint>& keypointsImage) const
{
	double a[3],b[3],c[3];

	if (!computeOrthoRectificationParams(keypoints3D,keypointsImage,a,b,c))
		return 0;

	const double& a0 = a[0];
	const double& a1 = a[1];
	const double& a2 = a[2];
	const double& b0 = b[0];
	const double& b1 = b[1];
	const double& b2 = b[2];
	//const double& c0 = c[0];
	const double& c1 = c[1];
	const double& c2 = c[2];

	PointCoordinateType defaultZ = 0;

	ccPointCloud* proj = new ccPointCloud(getName()+QString(".ortho-rectified"));
	if (!proj->reserve(m_width*m_height))
	{
		delete proj;
		return 0;
	}

	if (!proj->reserveTheRGBTable())
	{
		delete proj;
		return 0;
	}
	proj->showColors(true);

	unsigned realCount = 0;

	//ortho rectification
	{
		for (unsigned pi = 0; pi<m_width; ++pi)
		{
			double xi = static_cast<PointCoordinateType>(pi) - 0.5*static_cast<PointCoordinateType>(m_width);
			for (unsigned pj = 0; pj<m_height; ++pj)
			{
				double yi = static_cast<PointCoordinateType>(pj) - 0.5*static_cast<PointCoordinateType>(m_height);
				double qi = 1.0 + c1*xi + c2*yi;
				CCVector3 P(static_cast<PointCoordinateType>((a0+a1*xi+a2*yi)/qi),
							static_cast<PointCoordinateType>((b0+b1*xi+b2*yi)/qi),
							defaultZ);

				//and color?
				QRgb rgb = m_image.pixel(pi,pj);
				int r = qRed(rgb);
				int g = qGreen(rgb);
				int b = qBlue(rgb);
				if (r+g+b > 0)
				{
					//add point
					proj->addPoint(P);
					//and color
					colorType C[3] = {	static_cast<colorType>(r),
										static_cast<colorType>(g),
										static_cast<colorType>(b) };
					proj->addRGBColor(C);
					++realCount;
				}
			}
		}
	}

	if (realCount == 0)
	{
		delete proj;
		proj = 0;
	}
	else
	{
		proj->resize(realCount);
	}

	return proj;
}