TVectorImageP Naa2TlvConverter::vectorize(const TToonzImageP &ti) { CenterlineConfiguration conf; if (!ti) return TVectorImageP(); TPalette *palette = ti->getPalette(); VectorizerCore vc; TAffine dpiAff; double factor = Stage::inch; double dpix = factor / 72, dpiy = factor / 72; ti->getDpi(dpix, dpiy); TPointD center = ti->getRaster()->getCenterD(); if (dpix != 0.0 && dpiy != 0.0) dpiAff = TScale(factor / dpix, factor / dpiy); factor = norm(dpiAff * TPointD(1, 0)); conf.m_affine = dpiAff * TTranslation(-center); conf.m_thickScale = factor; conf.m_leaveUnpainted = false; conf.m_makeFrame = true; conf.m_penalty = 0.0; conf.m_despeckling = 0; TImageP img(ti.getPointer()); TVectorImageP vi = vc.vectorize(img, conf, palette); vi->setPalette(palette); return vi; }
void MorphTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { m_lastPos = m_firstPos = pos; int index = deformation.getClosest(pos); if (index >= 0) deformation.m_selected = index; else deformation.m_selected = -1; if (m_vi && index >= 0) { m_vi2 = m_vi->clone(); deformation.deform(m_vi2.getPointer(), m_vi.getPointer()); } else { m_vi2 = TVectorImageP(); } }
TImageP TImageReader::load0() { if (!m_reader && !m_vectorReader) open(); if (m_reader) { TImageInfo info = m_reader->getImageInfo(); if (info.m_lx <= 0 || info.m_ly <= 0) return TImageP(); // Initialize raster info assert(m_shrink > 0); // Build loading rect int x0 = 0; int x1 = info.m_lx - 1; int y0 = 0; int y1 = info.m_ly - 1; if (!m_region.isEmpty()) { // Intersect with the externally specified loading region x0 = tmax(x0, m_region.x0); y0 = tmax(y0, m_region.y0); x1 = tmin(x1, m_region.x1); y1 = tmin(y1, m_region.y1); if (x0 >= x1 || y0 >= y1) return TImageP(); } if (m_shrink > 1) { // Crop to shrink multiples x1 -= (x1 - x0) % m_shrink; y1 -= (y1 - y0) % m_shrink; } assert(x0 <= x1 && y0 <= y1); TDimension imageDimension = TDimension((x1 - x0) / m_shrink + 1, (y1 - y0) / m_shrink + 1); if (m_path.getType() == "tzp" || m_path.getType() == "tzu") { // Colormap case TRasterCM32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); // Build the savebox TRect saveBox(info.m_x0, info.m_y0, info.m_x1, info.m_y1); if (!m_region.isEmpty()) { // Intersect with the loading rect if (m_region.overlaps(saveBox)) { saveBox *= m_region; int sbx0 = saveBox.x0 - m_region.x0; int sby0 = saveBox.y0 - m_region.y0; int sbx1 = sbx0 + saveBox.getLx() - 1; int sby1 = sby0 + saveBox.getLy() - 1; assert(sbx0 >= 0); assert(sby0 >= 0); assert(sbx1 >= 0); assert(sby1 >= 0); saveBox = TRect(sbx0, sby0, sbx1, sby1); } else saveBox = TRect(0, 0, 1, 1); } if (m_shrink > 1) { saveBox.x0 = saveBox.x0 / m_shrink; saveBox.y0 = saveBox.y0 / m_shrink; saveBox.x1 = saveBox.x1 / m_shrink; saveBox.y1 = saveBox.y1 / m_shrink; } TToonzImageP ti(ras, ras->getBounds() * saveBox); ti->setDpi(info.m_dpix, info.m_dpiy); return ti; } else if (info.m_bitsPerSample >= 8) { // Common byte-based rasters (see below, we have black-and-white bit-based images too) if (info.m_samplePerPixel == 1 && m_readGreytones) { // Greymap case // NOTE: Uses a full 32-bit raster first, and then copies down to the GR8 // Observe that GR16 file images get immediately down-cast to GR8... // Should we implement that too? TRasterGR8P ras(imageDimension); readRaster_copyLines(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); TRasterImageP ri(ras); ri->setDpi(info.m_dpix, info.m_dpiy); return ri; } // assert(info.m_samplePerPixel == 3 || info.m_samplePerPixel == 4); TRasterP _ras; if (info.m_bitsPerSample == 16) { if (m_is64BitEnabled || m_path.getType() != "tif") { // Standard 64-bit case. // Also covers down-casting to 32-bit from a 64-bit image file whenever // not a tif file (see below). TRaster64P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); _ras = ras; } else { // The Tif reader has got an automatically down-casting readLine(char*, ...) // in case the input file is 64-bit. The advantage is that no intermediate // 64-bit raster is required in this case. TRaster32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); _ras = ras; } } else if (info.m_bitsPerSample == 8) { // Standard 32-bit case TRaster32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); _ras = ras; } else throw TImageException(m_path, "Image format not supported"); // 64-bit to 32-bit conversions if necessary (64 bit images not allowed) if (!m_is64BitEnabled && (TRaster64P)_ras) { TRaster32P raux(_ras->getLx(), _ras->getLy()); TRop::convert(raux, _ras); _ras = raux; } // Return the image TRasterImageP ri(_ras); ri->setDpi(info.m_dpix, info.m_dpiy); return ri; } else if (info.m_samplePerPixel == 1 && info.m_valid == true) { // Previously dubbed as 'Palette cases'. No clue about what is this... :| TRaster32P ras(imageDimension); readRaster(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); TRasterImageP ri(ras); ri->setDpi(info.m_dpix, info.m_dpiy); return ri; } else if (info.m_samplePerPixel == 1 && m_readGreytones) { // Black-and-White case, I guess. Standard greymaps were considered above... TRasterGR8P ras(imageDimension); readRaster_copyLines(ras, m_reader, x0, y0, x1, y1, info.m_lx, info.m_ly, m_shrink); TRasterImageP ri(ras); ri->setDpi(info.m_dpix, info.m_dpiy); if (info.m_bitsPerSample == 1) // I suspect this always evaluates true... ri->setScanBWFlag(true); return ri; } else return TImageP(); } else if (m_vectorReader) { TVectorImage *vi = m_vectorReader->read(); return TVectorImageP(vi); } else return TImageP(); }
void MorphTool::leftButtonUp(const TPointD &pos, const TMouseEvent &e) { m_vi2 = TVectorImageP(); }