DColor ImageIface::colorInfoFromOriginal(const QPoint& point) const { if (!original() || original()->isNull()) { kWarning() << "No image data available!"; return DColor(); } if (point.x() > originalSize().width() || point.y() > originalSize().height()) { kWarning() << "Coordinate out of range!"; return DColor(); } return original()->getPixelColor(point.x(), point.y()); }
void ShearTool::setPreviewImage() { ImageIface* const iface = d->previewWidget->imageIface(); int w = iface->previewSize().width(); int h = iface->previewSize().height(); DImg imTemp = filter()->getTargetImage().smoothScale(w, h, Qt::KeepAspectRatio); DImg imDest( w, h, filter()->getTargetImage().sixteenBit(), filter()->getTargetImage().hasAlpha() ); imDest.fill( DColor(d->previewWidget->palette().color(QPalette::Background).rgb(), filter()->getTargetImage().sixteenBit()) ); imDest.bitBltImage(&imTemp, (w-imTemp.width())/2, (h-imTemp.height())/2); iface->setPreview(imDest.smoothScale(iface->previewSize())); d->previewWidget->updatePreview(); ShearFilter* const tool = dynamic_cast<ShearFilter*>(filter()); if (tool) { QSize newSize = tool->getNewSize(); QString temp; d->newWidthLabel->setText(temp.setNum( newSize.width()) + i18n(" px") ); d->newHeightLabel->setText(temp.setNum( newSize.height()) + i18n(" px") ); } }
void DGSPictureLayer::updateCustomGpuParameter( DShaderObject* so ) { if (!so->isValid()) { return; } so->getVertexProgramParameters()->setValue("quadTransform", mQuadTransform); so->getVertexProgramParameters()->setValue("uvTransform", mUVTransform); if (mTexture) { DTexture* tex = mTexture->getAs<DTexture>(false); if (tex != NULL) { so->getPixelProgramParameters()->setValue("texUnit", tex->getGpuTexutureConstant()); } else { so->getPixelProgramParameters()->setValue("texUnit", NULL); } so->getPixelProgramParameters()->setValue("texUnit", mTexSampler); } so->getPixelProgramParameters()->setValue("colorOffset", DColor(0.0f,0.0f,0.0f, 1.0f)); }
DColor ImageIface::colorInfoFromTargetPreview(const QPoint& point) const { if (d->targetPreviewImage.isNull() || point.x() > d->previewWidth || point.y() > d->previewHeight) { kWarning() << "Coordinate out of range or no image data available!"; return DColor(); } return d->targetPreviewImage.getPixelColor(point.x(), point.y()); }
void SharpenFilter::convolveImageMultithreaded(const Args& prm) { double maxClamp = m_destImage.sixteenBit() ? 16777215.0 : 65535.0; double* k = 0; double red, green, blue, alpha; int mx, my, sx, sy, mcx, mcy; DColor color; for (uint x = prm.start ; runningFlag() && (x < prm.stop) ; ++x) { k = prm.normal_kernel; red = green = blue = alpha = 0; sy = prm.y - prm.halfKernelWidth; for (mcy = 0 ; runningFlag() && (mcy < prm.kernelWidth) ; ++mcy, ++sy) { my = sy < 0 ? 0 : sy > (int)m_destImage.height() - 1 ? m_destImage.height() - 1 : sy; sx = x + (-prm.halfKernelWidth); for (mcx = 0 ; runningFlag() && (mcx < prm.kernelWidth) ; ++mcx, ++sx) { mx = sx < 0 ? 0 : sx > (int)m_destImage.width() - 1 ? m_destImage.width() - 1 : sx; color = m_orgImage.getPixelColor(mx, my); red += (*k) * (color.red() * 257.0); green += (*k) * (color.green() * 257.0); blue += (*k) * (color.blue() * 257.0); alpha += (*k) * (color.alpha() * 257.0); ++k; } } red = red < 0.0 ? 0.0 : red > maxClamp ? maxClamp : red + 0.5; green = green < 0.0 ? 0.0 : green > maxClamp ? maxClamp : green + 0.5; blue = blue < 0.0 ? 0.0 : blue > maxClamp ? maxClamp : blue + 0.5; alpha = alpha < 0.0 ? 0.0 : alpha > maxClamp ? maxClamp : alpha + 0.5; m_destImage.setPixelColor(x, prm.y, DColor((int)(red / 257UL), (int)(green / 257UL), (int)(blue / 257UL), (int)(alpha / 257UL), m_destImage.sixteenBit())); } }
void BorderFilter::Private::setup(const DImg& m_orgImage) { solidColor = DColor(settings.solidColor, m_orgImage.sixteenBit()); niepceBorderColor = DColor(settings.niepceBorderColor, m_orgImage.sixteenBit()); niepceLineColor = DColor(settings.niepceLineColor, m_orgImage.sixteenBit()); bevelUpperLeftColor = DColor(settings.bevelUpperLeftColor, m_orgImage.sixteenBit()); bevelLowerRightColor = DColor(settings.bevelLowerRightColor, m_orgImage.sixteenBit()); decorativeFirstColor = DColor(settings.decorativeFirstColor, m_orgImage.sixteenBit()); decorativeSecondColor = DColor(settings.decorativeSecondColor, m_orgImage.sixteenBit()); if (settings.preserveAspectRatio) { orgRatio = (float)settings.orgWidth / (float)settings.orgHeight; int size = qMin(m_orgImage.height(), m_orgImage.width()); borderMainWidth = (int)(size * settings.borderPercent); border2ndWidth = (int)(size * 0.005); // Clamp internal border with to 1 pixel to be visible with small image. if (border2ndWidth < 1) { border2ndWidth = 1; } } }
void HSLFilter::applyHSL(DImg& image) { if (image.isNull()) { return; } bool sixteenBit = image.sixteenBit(); uint numberOfPixels = image.numPixels(); int progress; int hue, sat, lig; double vib = d->settings.vibrance; DColor color; if (sixteenBit) // 16 bits image. { unsigned short* data = (unsigned short*) image.bits(); for (uint i=0; runningFlag() && (i<numberOfPixels); ++i) { color = DColor(data[2], data[1], data[0], 0, sixteenBit); // convert RGB to HSL color.getHSL(&hue, &sat, &lig); // convert HSL to RGB color.setHSL(d->htransfer16[hue], vibranceBias(d->stransfer16[sat], hue, vib, sixteenBit), d->ltransfer16[lig], sixteenBit); data[2] = color.red(); data[1] = color.green(); data[0] = color.blue(); data += 4; progress = (int)(((double)i * 100.0) / numberOfPixels); if ( progress%5 == 0 ) { postProgress( progress ); } } } else // 8 bits image. { uchar* data = image.bits(); for (uint i=0; runningFlag() && (i<numberOfPixels); ++i) { color = DColor(data[2], data[1], data[0], 0, sixteenBit); // convert RGB to HSL color.getHSL(&hue, &sat, &lig); // convert HSL to RGB color.setHSL(d->htransfer[hue], vibranceBias(d->stransfer[sat],hue,vib,sixteenBit), d->ltransfer[lig], sixteenBit); data[2] = color.red(); data[1] = color.green(); data[0] = color.blue(); data += 4; progress = (int)(((double)i * 100.0) / numberOfPixels); if ( progress%5 == 0 ) { postProgress( progress ); } } } }
void ShearFilter::filterImage() { int progress; register int x, y, p = 0, pt; int new_width, new_height; double nx, ny, dx, dy; double horz_factor, vert_factor; double horz_add, vert_add; double horz_beta_angle, vert_beta_angle; int nWidth = m_orgImage.width(); int nHeight = m_orgImage.height(); uchar* pBits = m_orgImage.bits(); unsigned short* pBits16 = reinterpret_cast<unsigned short*>(m_orgImage.bits()); // get beta ( complementary ) angle for horizontal and vertical angles horz_beta_angle = (((d->hAngle < 0.0) ? 180.0 : 90.0) - d->hAngle) * DEG2RAD; vert_beta_angle = (((d->vAngle < 0.0) ? 180.0 : 90.0) - d->vAngle) * DEG2RAD; // get new distance for width and height values horz_add = nHeight * ((d->hAngle < 0.0) ? sin(horz_beta_angle) : cos(horz_beta_angle)); vert_add = nWidth * ((d->vAngle < 0.0) ? sin(vert_beta_angle) : cos(vert_beta_angle)); // get absolute values for the distances horz_add = fabs(horz_add); vert_add = fabs(vert_add); // get new image size ( original size + distance ) new_width = (int)horz_add + nWidth; new_height = (int)vert_add + nHeight; // get scale factor for width and height horz_factor = horz_add / new_height; vert_factor = vert_add / new_width; // if horizontal angle is greater than zero... // else, initial distance is equal to maximum distance ( in negative form ) if (d->hAngle > 0.0) { // initial distance is zero and scale is negative ( to decrease ) dx = 0; horz_factor *= -1.0; } else { dx = -horz_add; } // if vertical angle is greater than zero... // else, initial distance is equal to maximum distance ( in negative form ) if (d->vAngle > 0.0) { // initial distance is zero and scale is negative ( to decrease ) dy = 0; vert_factor *= -1.0; } else { dy = -vert_add; } // allocates a new image with the new size bool sixteenBit = m_orgImage.sixteenBit(); m_destImage = DImg(new_width, new_height, sixteenBit, m_orgImage.hasAlpha()); m_destImage.fill(DColor(d->backgroundColor.rgb(), sixteenBit)); uchar* pResBits = m_destImage.bits(); unsigned short* pResBits16 = reinterpret_cast<unsigned short*>(m_destImage.bits()); PixelsAliasFilter alias; for (y = 0; y < new_height; ++y) { for (x = 0; x < new_width; ++x, p += 4) { // get new positions nx = x + dx + y * horz_factor; ny = y + dy + x * vert_factor; // if is inside the source image if (isInside(nWidth, nHeight, lround(nx), lround(ny))) { if (d->antiAlias) { if (!sixteenBit) alias.pixelAntiAliasing(pBits, nWidth, nHeight, nx, ny, &pResBits[p + 3], &pResBits[p + 2], &pResBits[p + 1], &pResBits[p]); else alias.pixelAntiAliasing16(pBits16, nWidth, nHeight, nx, ny, &pResBits16[p + 3], &pResBits16[p + 2], &pResBits16[p + 1], &pResBits16[p]); } else { pt = setPosition(nWidth, lround(nx), lround(ny)); for (int z = 0 ; z < 4 ; ++z) { if (!sixteenBit) { pResBits[p + z] = pBits[pt + z]; } else { pResBits16[p + z] = pBits16[pt + z]; } } } } } // Update the progress bar in dialog. progress = (int)(((double)y * 100.0) / new_height); if (progress % 5 == 0) { postProgress(progress); } } // To compute the rotated destination image size using original image dimensions. int W = (int)(fabs(d->orgH * ((d->hAngle < 0.0) ? sin(horz_beta_angle) : cos(horz_beta_angle)))) + d->orgW; int H = (int)(fabs(d->orgW * ((d->vAngle < 0.0) ? sin(vert_beta_angle) : cos(vert_beta_angle)))) + d->orgH; d->newSize.setWidth(W); d->newSize.setHeight(H); }
void FreeRotationFilter::filterImage() { int progress; register int w, h, nw, nh, j, i = 0; int nNewHeight, nNewWidth; int nhdx, nhdy, nhsx, nhsy; double lfSin, lfCos, lfx, lfy; int nWidth = m_orgImage.width(); int nHeight = m_orgImage.height(); uchar* pBits = m_orgImage.bits(); unsigned short* pBits16 = (unsigned short*)m_orgImage.bits(); // first of all, we need to calculate the sin and cos of the given angle lfSin = sin(d->settings.angle * -d->DEG2RAD); lfCos = cos(d->settings.angle * -d->DEG2RAD); // now, we have to calc the new size for the destination image if ((lfSin * lfCos) < 0) { nNewWidth = lround (fabs (nWidth * lfCos - nHeight * lfSin)); nNewHeight = lround (fabs (nWidth * lfSin - nHeight * lfCos)); } else { nNewWidth = lround (fabs (nWidth * lfCos + nHeight * lfSin)); nNewHeight = lround (fabs (nWidth * lfSin + nHeight * lfCos)); } // getting the destination's center position nhdx = nNewWidth / 2; nhdy = nNewHeight / 2; // getting the source's center position nhsx = nWidth / 2; nhsy = nHeight / 2; // now, we have to alloc a new image bool sixteenBit = m_orgImage.sixteenBit(); m_destImage = DImg(nNewWidth, nNewHeight, sixteenBit, m_orgImage.hasAlpha()); if (m_destImage.isNull()) { return; } m_destImage.fill( DColor(d->settings.backgroundColor.rgb(), sixteenBit) ); uchar* pResBits = m_destImage.bits(); unsigned short* pResBits16 = (unsigned short*)m_destImage.bits(); PixelsAliasFilter alias; // main loop for (h = 0; runningFlag() && (h < nNewHeight); ++h) { nh = h - nhdy; for (w = 0; runningFlag() && (w < nNewWidth); ++w) { nw = w - nhdx; i = setPosition (nNewWidth, w, h); lfx = (double)nw * lfCos - (double)nh * lfSin + nhsx; lfy = (double)nw * lfSin + (double)nh * lfCos + nhsy; if (isInside (nWidth, nHeight, (int)lfx, (int)lfy)) { if (d->settings.antiAlias) { if (!sixteenBit) alias.pixelAntiAliasing(pBits, nWidth, nHeight, lfx, lfy, &pResBits[i+3], &pResBits[i+2], &pResBits[i+1], &pResBits[i]); else alias.pixelAntiAliasing16(pBits16, nWidth, nHeight, lfx, lfy, &pResBits16[i+3], &pResBits16[i+2], &pResBits16[i+1], &pResBits16[i]); } else { j = setPosition (nWidth, (int)lfx, (int)lfy); for (int p = 0 ; p < 4 ; ++p) { if (!sixteenBit) { pResBits[i] = pBits[j]; } else { pResBits16[i] = pBits16[j]; } ++i; ++j; } } } } // Update the progress bar in dialog. progress = (int) (((double) h * 100.0) / nNewHeight); if (progress % 5 == 0) { postProgress(progress); } } // Compute the rotated destination image size using original image dimensions. int W, H; double absAngle = fabs(d->settings.angle); // stop here when no angle was set if (absAngle == 0.0) { return; } if (absAngle < 90.0) { W = (int)(d->settings.orgW * cos(absAngle * d->DEG2RAD) + d->settings.orgH * sin(absAngle * d->DEG2RAD)); H = (int)(d->settings.orgH * cos(absAngle * d->DEG2RAD) + d->settings.orgW * sin(absAngle * d->DEG2RAD)); } else { H = (int)(d->settings.orgW * cos((absAngle-90.0) * d->DEG2RAD) + d->settings.orgH * sin((absAngle-90.0) * d->DEG2RAD)); W = (int)(d->settings.orgH * cos((absAngle-90.0) * d->DEG2RAD) + d->settings.orgW * sin((absAngle-90.0) * d->DEG2RAD)); } // Auto-cropping destination image without black holes around. QRect autoCrop; switch (d->settings.autoCrop) { case FreeRotationContainer::WidestArea: { // 'Widest Area' method (by Renchi Raju). autoCrop.setX((int) (nHeight * sin(absAngle * d->DEG2RAD))); autoCrop.setY((int) (nWidth * sin(absAngle * d->DEG2RAD))); autoCrop.setWidth((int) (nNewWidth - 2* nHeight * sin(absAngle * d->DEG2RAD))); autoCrop.setHeight((int) (nNewHeight - 2* nWidth * sin(absAngle * d->DEG2RAD))); if (!autoCrop.isValid()) { m_destImage = DImg(m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit(), m_orgImage.hasAlpha()); m_destImage.fill(DColor(d->settings.backgroundColor.rgb(), sixteenBit)); d->settings.newSize = QSize(); } else { m_destImage = m_destImage.copy(autoCrop); d->settings.newSize.setWidth((int) (W - 2* d->settings.orgH * sin(absAngle * d->DEG2RAD))); d->settings.newSize.setHeight((int) (H - 2* d->settings.orgW * sin(absAngle * d->DEG2RAD))); } break; } case FreeRotationContainer::LargestArea: { // 'Largest Area' method (by Gerhard Kulzer). float gamma = 0.0f; if (nHeight > nWidth) { gamma = atan((float) nWidth / (float) nHeight); if (absAngle < 90.0) { autoCrop.setHeight((int) ((float) nWidth / cos(absAngle * d->DEG2RAD) / (tan(gamma) + tan(absAngle * d->DEG2RAD)))); autoCrop.setWidth((int) ((float) autoCrop.height() * tan(gamma))); } else { autoCrop.setWidth((int) ((float) nWidth / cos((absAngle - 90.0) * d->DEG2RAD) / (tan(gamma) + tan((absAngle - 90.0) * d->DEG2RAD)))); autoCrop.setHeight((int) ((float) autoCrop.width() * tan(gamma))); } } else { gamma = atan((float) nHeight / (float) nWidth); if (absAngle < 90.0) { autoCrop.setWidth((int) ((float) nHeight / cos(absAngle * d->DEG2RAD) / (tan(gamma) + tan(absAngle * d->DEG2RAD)))); autoCrop.setHeight((int) ((float) autoCrop.width() * tan(gamma))); } else { autoCrop.setHeight((int) ((float) nHeight / cos((absAngle - 90.0) * d->DEG2RAD) / (tan(gamma) + tan((absAngle - 90.0) * d->DEG2RAD)))); autoCrop.setWidth((int) ((float) autoCrop.height() * tan(gamma))); } } autoCrop.moveCenter(QPoint(nNewWidth / 2, nNewHeight / 2)); if (!autoCrop.isValid()) { m_destImage = DImg(m_orgImage.width(), m_orgImage.height(), m_orgImage.sixteenBit(), m_orgImage.hasAlpha()); m_destImage.fill(DColor(d->settings.backgroundColor.rgb(), sixteenBit)); d->settings.newSize = QSize(); } else { m_destImage = m_destImage.copy(autoCrop); gamma = atan((float) d->settings.orgH / (float) d->settings.orgW); if (absAngle < 90.0) { d->settings.newSize.setWidth((int) ((float) d->settings.orgH / cos(absAngle * d->DEG2RAD) / (tan(gamma) + tan(absAngle * d->DEG2RAD)))); d->settings.newSize.setHeight((int) ((float) d->settings.newSize.width() * tan(gamma))); } else { d->settings.newSize.setHeight((int) ((float) d->settings.orgH / cos((absAngle - 90.0) * d->DEG2RAD) / (tan(gamma) + tan((absAngle - 90.0) * d->DEG2RAD)))); d->settings.newSize.setWidth((int) ((float) d->settings.newSize.height() * tan(gamma))); } } break; } default: // No auto cropping. { d->settings.newSize.setWidth(W); d->settings.newSize.setHeight(H); break; } } }
DGSPictureLayer::DGSPictureLayer() : mRenderSize(0.0f, 0.0f), mClipLeft(0.0f), mClipRight(0.0f), mClipTop(0.0f), mClipBottom(0.0f), mAlignment(0), mbScalable(false), mbDirty(true) { mWorldTransform = DMatrix4::IDENTITY; mQuadTransform = DMatrix4::IDENTITY; mUVTransform = DMatrix3::IDENTITY; mRenderEffect = DResourceGroupManager::getSingleton(). getResouceManager("RenderEffect")->getResource( "_BasicShaderPack", "UI_Basic.dre"); mRenderEffect->touch(); mTexture = DResourceGroupManager::getSingleton(). getResouceManager("Texture")->getResource("_BasicMediaPack", "T_debug_default.dds"); mTexture->touch(); DRenderResourceManager* hm = DRenderResourceManager::getSingletonPtr(); mRenderLayout = hm->createRenderLayout(); mRenderLayout->setTopologyType(PT_TriangleList); mVDecl.addElement(0, 0, VET_Float3, VES_Position); mVDecl.addElement(0, sizeof(DReal)*3, VET_Float2, VES_TexCoord); mVDecl.sort(); size_t vertSize = mVDecl.getVertexSize(0); DVertexBufferPtr vb = hm->createVetexBuffer(vertSize, 4, HBU_Static, false); // a quad. float data[] = { /*vert*/ -1.0f, 1.0f, 0.0f, /*uv*/ 0.0f, 0.0f, /*vert*/ 1.0f, 1.0f, 0.0f, /*uv*/ 1.0f, 0.0f, /*vert*/ 1.0f, -1.0f, 0.0f, /*uv*/ 1.0f, 1.0f, /*vert*/ -1.0f,-1.0f, 0.0f, /*uv*/ 0.0f, 1.0f }; vb->writeData(0, vb->getSize(), data, true); mIndices = hm->createIndexBuffer(IT_16Bit, 6, HBU_Static, false); int16 idata[] = { 0, 3, 2, 0, 2, 1 }; mIndices->writeData(0, mIndices->getSize(), idata, true); mVStream.setStream(0, vb); mRenderLayout->setIndexData(DIndexData(mIndices)); mRenderLayout->setVertexData(DVertexData(mVStream, mVDecl)); mRenderLayout->seal(); DTextureSampler texSampler; texSampler.addressU = TAM_Border; texSampler.addressV = TAM_Border; texSampler.addressW = TAM_Border; texSampler.minFilter = FO_Linear; texSampler.magFilter = FO_Linear; texSampler.mipFilter = FO_None; texSampler.borderColor = DColor(0.0f, 0.0f, 0.0f, 0.0f); mTexSampler = hm->createTextureSamplerObject(texSampler); }