//!Converts a TVectorImage into a TRasterImage. The input vector image //!is transformed through the passed affine \b aff, and put into a //!TRasterImage strictly covering the bounding box of the transformed //!vector image. The output image has its lower-left position in the //!world reference specified by the \b pos parameter, which is granted to //!be an integer displacement of the passed value. Additional parameters //!include an integer \b enlarge by which the output image is enlarged with //!respect to the transformed image's bbox, and the bool \b transformThickness //!to specify whether the transformation should involve strokes' thickensses //!or not. TRasterImageP TRasterImageUtils::vectorToFullColorImage( const TVectorImageP &vimage, const TAffine &aff, TPalette *palette, const TPointD &outputPos, const TDimension &outputSize, const std::vector<TRasterFxRenderDataP> *fxs, bool transformThickness) { if (!vimage || !palette) return 0; //Transform the vector image through aff TVectorImageP vi = vimage->clone(); vi->transform(aff, transformThickness); //Allocate the output ToonzImage TRaster32P raster(outputSize.lx, outputSize.ly); raster->clear(); TRasterImageP ri(raster); ri->setPalette(palette->clone()); //Shift outputPos to the origin vi->transform(TTranslation(-outputPos)); int strokeCount = vi->getStrokeCount(); std::vector<int> strokeIndex(strokeCount); std::vector<TStroke *> strokes(strokeCount); int i; for (i = 0; i < strokeCount; ++i) { strokeIndex[i] = i; strokes[i] = vi->getStroke(i); } vi->notifyChangedStrokes(strokeIndex, strokes); int maxStyleId = palette->getStyleCount() - 1; for (i = 0; i < (int)vi->getRegionCount(); ++i) { TRegion *region = vi->getRegion(i); fastAddPaintRegion(ri, region, tmin(maxStyleId, region->getStyle()), maxStyleId); } set<int> colors; if (fxs) { for (i = 0; i < (int)fxs->size(); i++) { SandorFxRenderData *sandorData = dynamic_cast<SandorFxRenderData *>((*fxs)[i].getPointer()); if (sandorData && sandorData->m_type == BlendTz) { std::string indexes = toString(sandorData->m_blendParams.m_colorIndex); std::vector<std::string> items; parseIndexes(indexes, items); PaletteFilterFxRenderData paletteFilterData; insertIndexes(items, &paletteFilterData); colors = paletteFilterData.m_colors; break; } } } for (i = 0; i < strokeCount; ++i) { TStroke *stroke = vi->getStroke(i); bool visible = false; int styleId = stroke->getStyle(); TColorStyleP style = palette->getStyle(styleId); assert(style); int colorCount = style->getColorParamCount(); if (colorCount == 0) visible = true; else { visible = false; for (int j = 0; j < style->getColorParamCount() && !visible; j++) { TPixel32 color = style->getColorParamValue(j); if (color.m != 0) visible = true; } } if (visible) fastAddInkStroke(ri, stroke, TRectD(), 1, true); } return ri; }
QString ImageBuilder::add(const TImageP &img, const TAffine &aff) { if (fabs(aff.det()) < 0.001) return ""; if (m_img && (m_img->getType() != img->getType())) return "Image type mismatch"; if (!m_img && img->getType() != TImage::VECTOR && m_width > 0 && m_height > 0) { TRasterP ras = img->raster()->create(m_width, m_height); if (img->getType() == TImage::RASTER) m_img = TRasterImageP(ras); else if (img->getType() == TImage::TOONZ_RASTER) { m_img = TToonzImageP(ras, ras->getBounds()); m_img->setPalette(img->getPalette()); } else return "Bad image type"; } if (!m_img && aff.isIdentity()) { m_img = img->cloneImage(); } else if (img->getType() == TImage::VECTOR) { // vector image if (!m_img) { // transform TVectorImageP vi = img->cloneImage(); vi->transform(aff); m_img = vi; } else { // merge TVectorImageP up = img; TVectorImageP dn = m_img; dn->mergeImage(up, aff); } } else { if (img->getType() != TImage::TOONZ_RASTER && img->getType() != TImage::RASTER) { // this should not ever happen return "Bad image type"; } TRasterP up = img->raster(); if (!m_img) { // create an empty bg TRasterP ras = up->create(); ras->clear(); if (img->getType() == TImage::TOONZ_RASTER) { TRasterCM32P rasCm = ras; m_img = TToonzImageP(rasCm, TRect(0, 0, ras->getLx() - 1, ras->getLy() - 1)); m_img->setPalette(img->getPalette()); } else { m_img = TRasterImageP(ras); } } TRasterP dn = m_img->raster(); if (aff.isTranslation() && aff.a13 == floor(aff.a13) && aff.a23 == floor(aff.a23)) { // just a integer coord translation TPoint delta = -up->getCenter() + dn->getCenter() + TPoint((int)aff.a13, (int)aff.a23); TRop::over(dn, up, delta); } else { TAffine aff1 = TTranslation(dn->getCenterD()) * aff * TTranslation(-up->getCenterD()); TRop::over(dn, up, aff1, TRop::Mitchell); } } return ""; }