void KisGmicSimpleConvertor::convertToGmicImage(KisPaintDeviceSP dev, gmic_image< float >& gmicImage) { const KoColorSpace *rgbaFloat32bitcolorSpace = KoColorSpaceRegistry::instance()->colorSpace(RGBAColorModelID.id(), Float32BitsColorDepthID.id(), KoColorSpaceRegistry::instance()->rgb8()->profile()); Q_CHECK_PTR(rgbaFloat32bitcolorSpace); dev->convertTo(rgbaFloat32bitcolorSpace); QRect rc = dev->exactBounds(); m_planarBytes = dev->readPlanarBytes(rc.x(), rc.y(), rc.width(), rc.height()); setChannelSize(rc.width() * rc.height()); int greenOffset = gmicImage._width * gmicImage._height; int blueOffset = greenOffset * 2; int alphaOffset = greenOffset * 3; quint8 * redChannelBytes = m_planarBytes.at(KoRgbF32Traits::red_pos); quint8 * greenChannelBytes = m_planarBytes.at(KoRgbF32Traits::green_pos); quint8 * blueChannelBytes = m_planarBytes.at(KoRgbF32Traits::blue_pos); quint8 * alphaChannelBytes = m_planarBytes.at(KoRgbF32Traits::alpha_pos); unsigned int channelSize = sizeof(float); memcpy(gmicImage._data ,redChannelBytes ,gmicImage._width * gmicImage._height * channelSize); memcpy(gmicImage._data + greenOffset ,greenChannelBytes ,gmicImage._width * gmicImage._height * channelSize); memcpy(gmicImage._data + blueOffset ,blueChannelBytes ,gmicImage._width * gmicImage._height * channelSize); memcpy(gmicImage._data + alphaOffset ,alphaChannelBytes ,gmicImage._width * gmicImage._height * channelSize); }
KisImageBuilder_Result CSVSaver::getLayer(CSVLayerRecord* layer, KisDocument* exportDoc, KisKeyframeSP keyframe, const QString &path, int frame, int idx) { //render to the temp layer KisImageWSP image = exportDoc->image(); KisPaintDeviceSP device = image->rootLayer()->firstChild()->projection(); layer->channel->fetchFrame(keyframe, device); QRect bounds = device->exactBounds(); if (bounds.isEmpty()) { layer->last = ""; //empty frame return KisImageBuilder_RESULT_OK; } layer->last = QString("frame%1-%2.png").arg(idx + 1,5,10,QChar('0')).arg(frame,5,10,QChar('0')); QString filename = path; filename.append(layer->last); //save to PNG KisSequentialConstIterator it(device, image->bounds()); const KoColorSpace* cs = device->colorSpace(); bool isThereAlpha = false; do { if (cs->opacityU8(it.oldRawData()) != OPACITY_OPAQUE_U8) { isThereAlpha = true; break; } } while (it.nextPixel()); if (!KisPNGConverter::isColorSpaceSupported(cs)) { device = new KisPaintDevice(*device.data()); KUndo2Command *cmd= device->convertTo(KoColorSpaceRegistry::instance()->rgb8()); delete cmd; } KisPNGOptions options; options.alpha = isThereAlpha; options.interlace = false; options.compression = 8; options.tryToSaveAsIndexed = false; options.transparencyFillColor = QColor(0,0,0); options.saveSRGBProfile = true; //TVPaint can use only sRGB options.forceSRGB = false; KisPNGConverter kpc(exportDoc); KisImageBuilder_Result result = kpc.buildFile(QUrl::fromLocalFile(filename), image->bounds(), image->xRes(), image->yRes(), device, image->beginAnnotations(), image->endAnnotations(), options, (KisMetaData::Store* )0 ); return result; }
void KisPaintDeviceTest::testColorSpaceConversion() { QImage image(QString(FILES_DATA_DIR) + QDir::separator() + "tile.png"); const KoColorSpace* srcCs = KoColorSpaceRegistry::instance()->rgb8(); const KoColorSpace* dstCs = KoColorSpaceRegistry::instance()->lab16(); KisPaintDeviceSP dev = new KisPaintDevice(srcCs); dev->convertFromQImage(image, 0); dev->move(10, 10); // Unalign with tile boundaries KUndo2Command* cmd = dev->convertTo(dstCs); QCOMPARE(dev->exactBounds(), QRect(10, 10, image.width(), image.height())); QCOMPARE(dev->pixelSize(), dstCs->pixelSize()); QVERIFY(*dev->colorSpace() == *dstCs); delete cmd; }
void KisFilterFastColorTransfer::processImpl(KisPaintDeviceSP device, const QRect& applyRect, const KisFilterConfiguration* config, KoUpdater* progressUpdater) const { Q_ASSERT(device != 0); dbgPlugins << "Start transferring color"; // Convert ref and src to LAB const KoColorSpace* labCS = KoColorSpaceRegistry::instance()->lab16(); if (!labCS) { dbgPlugins << "The LAB colorspace is not available."; return; } dbgPlugins << "convert a copy of src to lab"; const KoColorSpace* oldCS = device->colorSpace(); KisPaintDeviceSP srcLAB = new KisPaintDevice(*device.data()); dbgPlugins << "srcLab : " << srcLAB->extent(); KUndo2Command* cmd = srcLAB->convertTo(labCS, KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::internalConversionFlags()); delete cmd; if (progressUpdater) { progressUpdater->setRange(0, 2 * applyRect.width() * applyRect.height()); } int count = 0; // Compute the means and sigmas of src dbgPlugins << "Compute the means and sigmas of src"; double meanL_src = 0., meanA_src = 0., meanB_src = 0.; double sigmaL_src = 0., sigmaA_src = 0., sigmaB_src = 0.; KisSequentialConstIterator srcIt(srcLAB, applyRect); do { const quint16* data = reinterpret_cast<const quint16*>(srcIt.oldRawData()); quint32 L = data[0]; quint32 A = data[1]; quint32 B = data[2]; meanL_src += L; meanA_src += A; meanB_src += B; sigmaL_src += L * L; sigmaA_src += A * A; sigmaB_src += B * B; if (progressUpdater) progressUpdater->setValue(++count); } while (srcIt.nextPixel() && !(progressUpdater && progressUpdater->interrupted())); double totalSize = 1. / (applyRect.width() * applyRect.height()); meanL_src *= totalSize; meanA_src *= totalSize; meanB_src *= totalSize; sigmaL_src *= totalSize; sigmaA_src *= totalSize; sigmaB_src *= totalSize; dbgPlugins << totalSize << "" << meanL_src << "" << meanA_src << "" << meanB_src << "" << sigmaL_src << "" << sigmaA_src << "" << sigmaB_src; double meanL_ref = config->getDouble("meanL"); double meanA_ref = config->getDouble("meanA"); double meanB_ref = config->getDouble("meanB"); double sigmaL_ref = config->getDouble("sigmaL"); double sigmaA_ref = config->getDouble("sigmaA"); double sigmaB_ref = config->getDouble("sigmaB"); // Transfer colors dbgPlugins << "Transfer colors"; { double coefL = sqrt((sigmaL_ref - meanL_ref * meanL_ref) / (sigmaL_src - meanL_src * meanL_src)); double coefA = sqrt((sigmaA_ref - meanA_ref * meanA_ref) / (sigmaA_src - meanA_src * meanA_src)); double coefB = sqrt((sigmaB_ref - meanB_ref * meanB_ref) / (sigmaB_src - meanB_src * meanB_src)); KisHLineConstIteratorSP srcLABIt = srcLAB->createHLineConstIteratorNG(applyRect.x(), applyRect.y(), applyRect.width()); KisHLineIteratorSP dstIt = device->createHLineIteratorNG(applyRect.x(), applyRect.y(), applyRect.width()); quint16 labPixel[4]; for (int y = 0; y < applyRect.height() && !(progressUpdater && progressUpdater->interrupted()); ++y) { do { const quint16* data = reinterpret_cast<const quint16*>(srcLABIt->oldRawData()); labPixel[0] = (quint16)CLAMP(((double)data[0] - meanL_src) * coefL + meanL_ref, 0., 65535.); labPixel[1] = (quint16)CLAMP(((double)data[1] - meanA_src) * coefA + meanA_ref, 0., 65535.); labPixel[2] = (quint16)CLAMP(((double)data[2] - meanB_src) * coefB + meanB_ref, 0., 65535.); labPixel[3] = data[3]; oldCS->fromLabA16(reinterpret_cast<const quint8*>(labPixel), dstIt->rawData(), 1); if (progressUpdater) progressUpdater->setValue(++count); srcLABIt->nextPixel(); } while(dstIt->nextPixel()); dstIt->nextRow(); srcLABIt->nextRow(); } } }