示例#1
0
void Convert2Tlv::removeAntialias(TRasterCM32P &r)
{
	int threshold = (int)(m_antialiasValue * 255.0 / 100.0);
	int tone;
	for (int i = 0; i < r->getLy(); i++) {
		TPixelCM32 *pix = r->pixels(i);
		for (int j = 0; j < r->getLx(); j++, pix++)
			if ((tone = pix->getTone()) != 0xff) //tone==ff e tone==0 non vanno toccati mai
				pix->setTone(tone > threshold ? 0xff : 0);
	}
}
示例#2
0
/*--- Toonz Raster LevelのToneを拾う。 ---*/
int StylePicker::pickTone(const TPointD &pos) {
  if (TToonzImageP ti = m_image) {
    TRasterCM32P ras = ti->getRaster();
    if (!ras) return -1;
    TPoint point = getRasterPoint(pos);
    if (!ras->getBounds().contains(point)) return -1;
    TPixelCM32 col = ras->pixels(point.y)[point.x];

    return col.getTone();
  } else
    return -1;
}
示例#3
0
  bool compute(const TPoint &pin, int ink, bool isSelective) {
    TPixelCM32 *pix;
    int distance;
    TPixelCM32 *master;
    TPoint mp, sp;
    TPixelCM32 *slave;
    TPixelCM32 *d11, *d12, *d21, *d22;
    TPoint d1p1, d1p2, d2p1, d2p2;
    TPoint p = pin;

    if (!m_bBox.contains(p)) return false;

    if ((m_buf + p.y * m_wrap + p.x)->isPurePaint() &&
        ((p = nearestInk(p, 2)) == TPoint(-1, -1)))
      return false;

    pix = m_buf + p.y * m_wrap + p.x;

    /*-- 同じインクの場合はreturn --*/
    if (pix->getInk() == ink) return false;

    if (!ConnectionTable[neighboursCode(pix, p)]) {
      master = slave = pix;
      mp = sp  = p;
      distance = 0;
    } else
      distance = findTwinPoints(pix, p, master, mp, slave, sp);

    if (distance == -1) return false;

    if (!findDam(master, mp, slave, sp, distance, d11, d1p1, d12, d1p2))
      d11 = d12 = d21 = d22 = 0;
    else
      findDamRev(master, mp, slave, sp, distance, d21, d2p1, d22, d2p2);

    // vector<pair<TPixelCM32*, int> > oldInks;

    drawSegment(d1p1, d1p2, damInk, m_saver);
    drawSegment(d2p1, d2p2, damInk, m_saver);

    inkSegmentFill(p, ink, isSelective, m_saver);

    // UINT i;

    drawSegment(d1p1, d1p2, ink, m_saver);
    drawSegment(d2p1, d2p2, ink, m_saver);

    /*	for (i=0; i<oldInks.size(); i++)
    (oldInks[i].first)->setInk(ink);*/

    return true;
  }
示例#4
0
void InkSegmenter::drawSegment(
    const TPoint &p0, const TPoint &p1, int ink,
    /*vector<pair<TPixelCM32*, int> >& oldInks,*/ TTileSaverCM32 *saver) {
  int x, y, dx, dy, d, incr_1, incr_2;

  int x1 = p0.x;
  int y1 = p0.y;
  int x2 = p1.x;
  int y2 = p1.y;

  if (x1 > x2) {
    tswap(x1, x2);
    tswap(y1, y2);
  }

  TPixelCM32 *buf = m_r->pixels() + y1 * m_wrap + x1;
  /*if (buf->getInk()!=damInk)
          oldInks.push_back(pair<TPixelCM32*, int>(buf, buf->getInk()));
  if ((m_r->pixels() + y2*m_wrap + x2)->getInk()!=damInk)
          oldInks.push_back(pair<TPixelCM32*, int>(m_r->pixels() + y2*m_wrap +
  x2, (m_r->pixels() + y2*m_wrap + x2)->getInk()));*/

  if (saver) {
    saver->save(p0);
    saver->save(p1);
  }

  buf->setInk(ink);
  (m_r->pixels() + y2 * m_wrap + x2)->setInk(ink);

  dx = x2 - x1;
  dy = y2 - y1;

  x = y = 0;

  if (dy >= 0) {
    if (dy <= dx)
      DRAW_SEGMENT(x, y, dx, dy, (buf++), (buf += m_wrap + 1), SET_INK)
    else
      DRAW_SEGMENT(y, x, dy, dx, (buf += m_wrap), (buf += m_wrap + 1), SET_INK)
  } else {
/*-- (StylePickerTool内で)LineとAreaを切り替えてPickできる。mode: 0=Area, 1=Line, 2=Line&Areas(default)  --*/
int StylePicker::pickStyleId(const TPointD &pos, double radius2, int mode) const
{
	int styleId = 0;
	if (TToonzImageP ti = m_image) {
		TRasterCM32P ras = ti->getRaster();
		TPoint point = getRasterPoint(pos);
		if (!ras->getBounds().contains(point))
			return -1;
		TPixelCM32 col = ras->pixels(point.y)[point.x];

		switch (mode) {
		case 0: //AREAS
			styleId = col.getPaint();
			break;
		case 1: //LINES
			styleId = col.getInk();
			break;
		case 2: //ALL (Line & Area)
		default:
			styleId = col.isPurePaint() ? col.getPaint() : col.getInk();
			break;
		}
	} else if (TRasterImageP ri = m_image) {
		const TPalette *palette = m_palette.getPointer();
		if (!palette)
			return -1;
		TRaster32P ras = ri->getRaster();
		if (!ras)
			return -1;
		TPoint point = getRasterPoint(pos);
		if (!ras->getBounds().contains(point))
			return -1;
		TPixel32 col = ras->pixels(point.y)[point.x];
		styleId = palette->getClosestStyle(col);
	} else if (TVectorImageP vi = m_image) {
		// prima cerca lo stile della regione piu' vicina
		TRegion *r = vi->getRegion(pos);
		if (r)
			styleId = r->getStyle();
		// poi cerca quello della stroke, ma se prima aveva trovato una regione, richiede che
		// il click sia proprio sopra la stroke, altrimenti cerca la stroke piu' vicina (max circa 10 pixel)
		const double maxDist2 = (styleId == 0) ? 100.0 * radius2 : 0;
		bool strokeFound;
		double dist2, w, thick;
		UINT index;
		//!funzionerebbe ancora meglio con un getNearestStroke che considera
		//la thickness, cioe' la min distance dalla outline e non dalla centerLine
		strokeFound = vi->getNearestStroke(pos, w, index, dist2);
		if (strokeFound) {
			TStroke *stroke = vi->getStroke(index);
			thick = stroke->getThickPoint(w).thick;
			if (dist2 - thick * thick < maxDist2) {
				assert(stroke);
				styleId = stroke->getStyle();
			}
		}
	}
	return styleId;
}
示例#6
0
void inkFill(const TRasterCM32P &r, const TPoint &pin, int ink, int searchRay,
			 TTileSaverCM32 *saver, TRect *insideRect)
{
	r->lock();
	TPixelCM32 *pixels = (TPixelCM32 *)r->getRawData();
	int oldInk;
	TPoint p = pin;

	if ((pixels + p.y * r->getWrap() + p.x)->isPurePaint() && (searchRay == 0 ||
															   (p = nearestInk(r, p, searchRay)) == TPoint(-1, -1))) {
		r->unlock();
		return;
	}
	TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x);

	if (pix->getInk() == ink) {
		r->unlock();
		return;
	}

	oldInk = pix->getInk();

	std::stack<TPoint> seeds;
	seeds.push(p);

	while (!seeds.empty()) {
		p = seeds.top();
		seeds.pop();
		if (!r->getBounds().contains(p))
			continue;
		if (insideRect && !insideRect->contains(p))
			continue;

		TPixelCM32 *pix = pixels + (p.y * r->getWrap() + p.x);
		if (pix->isPurePaint() || pix->getInk() != oldInk)
			continue;

		if (saver)
			saver->save(p);

		pix->setInk(ink);

		seeds.push(TPoint(p.x - 1, p.y - 1));
		seeds.push(TPoint(p.x - 1, p.y));
		seeds.push(TPoint(p.x - 1, p.y + 1));
		seeds.push(TPoint(p.x, p.y - 1));
		seeds.push(TPoint(p.x, p.y + 1));
		seeds.push(TPoint(p.x + 1, p.y - 1));
		seeds.push(TPoint(p.x + 1, p.y));
		seeds.push(TPoint(p.x + 1, p.y + 1));
	}
	r->unlock();
}
示例#7
0
//-----------------------------------------------------------------------------
// questa funzione viene chiamata dopo il fill rect delle aree, e colora gli
// inchiostri di tipo "autoink"
// che confinano con le aree appena fillate con il rect. rbefore e' il rect del
// raster prima del rectfill.
void fillautoInks(TRasterCM32P &rin, TRect &rect, const TRasterCM32P &rbefore,
                  TPalette *plt) {
  assert(plt);
  TRasterCM32P r = rin->extract(rect);
  assert(r->getSize() == rbefore->getSize());
  int i, j;

  for (i = 0; i < r->getLy(); i++) {
    TPixelCM32 *pix  = r->pixels(i);
    TPixelCM32 *pixb = rbefore->pixels(i);
    for (j = 0; j < r->getLx(); j++, pix++, pixb++) {
      int paint = pix->getPaint();
      int tone  = pix->getTone();
      int ink   = pix->getInk();
      if (paint != pixb->getPaint() && tone > 0 && tone < 255 && ink != paint &&
          plt->getStyle(ink)->getFlags() != 0)
        inkFill(rin, TPoint(j, i) + rect.getP00(), paint, 0, NULL, &rect);
    }
  }
}
示例#8
0
void AreaFiller::rectFill(const TRect &rect, int color, bool onlyUnfilled,
                          bool fillPaints, bool fillInks) {
  // Viene trattato il caso fillInks
  /*- FillInkのみの場合 -*/
  if (!fillPaints) {
    assert(fillInks);
    assert(m_ras->getBounds().contains(rect));
    for (int y = rect.y0; y <= rect.y1; y++) {
      TPixelCM32 *pix = m_ras->pixels(y) + rect.x0;
      for (int x = rect.x0; x <= rect.x1; x++, pix++) pix->setInk(color);
    }
    return;
  }

  TRect r = m_bounds * rect;

  int dx = r.x1 - r.x0;
  int dy = (r.y1 - r.y0) * m_wrap;
  if (dx < 2 || dy < 2)  // rect degenere(area contenuta nulla), skippo.
    return;

  std::vector<int> frameSeed(2 * (r.getLx() + r.getLy() - 2));

  int x, y, count1, count2;
  /*- ptrをRect範囲のスタート地点に移動 -*/
  Pixel *ptr = m_pixels + r.y0 * m_wrap + r.x0;
  count1     = 0;
  count2     = r.y1 - r.y0 + 1;

  // Se il rettangolo non contiene il bordo del raster e se tutti i pixels
  // contenuti nel rettangolo sono pure paint non deve fare nulla!
  if (!rect.contains(m_bounds) && areRectPixelsPurePaint(m_pixels, r, m_wrap))
    return;

  // Viene riempito frameSeed con tutti i paint delle varie aree del rettangolo
  // di contorno.
  // Viene verificato se i pixels del rettangolo sono tutti pure paint.
  /*- 輪郭のPaintのIDをframeseed内に格納 -*/
  for (y = r.y0; y <= r.y1; y++, ptr += m_wrap, count1++, count2++) {
    if (r.x0 > 0) frameSeed[count1]                  = ptr->getPaint();
    if (r.x1 < m_ras->getLx() - 1) frameSeed[count2] = (ptr + dx)->getPaint();
  }
  ptr    = m_pixels + r.y0 * m_wrap + r.x0 + 1;
  count1 = count2;
  count2 = count1 + r.x1 - r.x0 - 1;
  for (x = r.x0 + 1; x < r.x1; x++, ptr++, count1++, count2++) {
    if (r.y0 > 0) frameSeed[count1]                  = ptr->getPaint();
    if (r.y1 < m_ras->getLy() - 1) frameSeed[count2] = (ptr + dy)->getPaint();
  }
  assert(count2 == 2 * (r.getLx() + r.getLy() - 2));

  // Viene fillato l'interno e il bordo del rettangolo rect con color
  Pixel *pix = m_pixels + r.y0 * m_wrap + r.x0;
  if (onlyUnfilled)
    for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) {
      for (x = r.x0; x <= r.x1; x++, pix++) {
        if (pix->getPaint() == 0)  // BackgroundStyle
          pix->setPaint(color);
        if (fillInks) pix->setInk(color);
      }
    }
  else
    for (y = r.y0; y <= r.y1; y++, pix += m_wrap - dx - 1) {
      for (x = r.x0; x <= r.x1; x++, pix++) {
        pix->setPaint(color);
        if (fillInks) pix->setInk(color);
      }
    }

  // Vengono fillati i pixel del rettangolo con i paint (mantenuti in frameSeed)
  // che
  // c'erano prima di fillare l'intero rettangolo, in questo modo si riportano
  // al colore originale le aree che non sono chiuse e non dovevano essere
  // fillate.
  count1 = 0;
  FillParameters params;
  // in order to make the paint to protlude behind the line
  params.m_prevailing = false;
  if (r.x0 > 0)
    for (y = r.y0; y <= r.y1; y++) {
      params.m_p       = TPoint(r.x0, y);
      params.m_styleId = frameSeed[count1++];
      fill(m_ras, params);
    }
  else
    count1 += r.y1 - r.y0 + 1;

  if (r.x1 < m_ras->getLx() - 1)
    for (y = r.y0; y <= r.y1; y++) {
      params.m_p       = TPoint(r.x1, y);
      params.m_styleId = frameSeed[count1++];
      fill(m_ras, params);
    }
  else
    count1 += r.y1 - r.y0 + 1;

  if (r.y0 > 0)
    for (x = r.x0 + 1; x < r.x1; x++) {
      params.m_p       = TPoint(x, r.y0);
      params.m_styleId = frameSeed[count1++];
      fill(m_ras, params);
    }
  else
    count1 += r.x1 - r.x0 - 1;

  if (r.y1 < m_ras->getLy() - 1)
    for (x = r.x0 + 1; x < r.x1; x++) {
      params.m_p       = TPoint(x, r.y1);
      params.m_styleId = frameSeed[count1++];
      fill(m_ras, params);
    }
}
示例#9
0
void Convert2Tlv::doFill(TRasterCM32P &rout, const TRaster32P &rin)
{
	//prima passata: si filla  solo partendo da pixel senza inchiostro, senza antialiasing(tone==255)
	for (int i = 0; i < rin->getLy(); i++) {
		TPixel *pixin = rin->pixels(i);
		TPixelCM32 *pixout = rout->pixels(i);
		for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
			if (!(pixout->getTone() == 255 && pixout->getPaint() == 0 && pixin->m == 255))
				continue;

			std::map<TPixel, int>::const_iterator it;
			int paintIndex;
			if ((it = m_colorMap.find(*pixin)) == m_colorMap.end()) {
				if (m_colorTolerance > 0)
					it = findNearestColor(*pixin);
				// if (it==colorMap.end() && (int)colorMap.size()>origColorCount) //se non l'ho trovato tra i colori origari, lo cerco in quelli nuovi, ma in questo caso deve essere esattamente uguale(tolerance = 0)
				//	 it  = findNearestColor(*pixin, colorMap, colorTolerance, origColorCount, colorMap.size()-1);

				if (it == m_colorMap.end() && m_lastIndex < 4096) {
					m_colorMap[*pixin] = ++m_lastIndex;
					paintIndex = m_lastIndex;
				} else if (it != m_colorMap.end()) {
					m_colorMap[*pixin] = it->second;
					paintIndex = it->second;
				}
			} else
				paintIndex = it->second;
			FillParameters params;
			params.m_p = TPoint(j, i);
			params.m_styleId = paintIndex;
			params.m_emptyOnly = true;
			fill(rout, params);
			//if (*((ULONG *)rout->getRawData())!=0xff)
			//  {
			//  int cavolo=0;
			//  }
		}
	}

	//seconda passata: se son rimasti pixel antialiasati non fillati, si fillano, cercando nelle vicinanze un pixel di paint puro per capire il colore da usare
	for (int i = 0; i < rin->getLy(); i++) {
		TPixel *pixin = rin->pixels(i);
		TPixelCM32 *pixout = rout->pixels(i);
		for (int j = 0; j < rin->getLx(); j++, pixin++, pixout++) {
			if (!(pixout->getTone() > 0 && pixout->getTone() < 255 && pixout->getPaint() == 0 && pixin->m == 255))
				continue;

			TPoint p = getClosestPurePaint(rout, i, j);
			if (p.x == -1)
				continue;

			//pixout->setPaint( paintIndex);
			FillParameters params;
			params.m_p = TPoint(j, i);
			params.m_styleId = (rout->pixels(p.y) + p.x)->getPaint();
			params.m_emptyOnly = true;

			fill(rout, params);
		}
	}

	//infine, si filla di trasparente lo sfondo, percorrendo il bordo, nel caso di trasbordamenti di colore
	TPixelCM32 *pixCm;
	TPixel *pix;

	pixCm = rout->pixels(0);
	pix = rin->pixels(0);
	FillParameters params;
	params.m_styleId = 0;

	for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(i, 0);
			fill(rout, params);
		}

	pixCm = rout->pixels(rout->getLy() - 1);
	pix = rin->pixels(rout->getLy() - 1);
	for (int i = 0; i < rout->getLx(); i++, pixCm++, pix++)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(i, rout->getLy() - 1);
			fill(rout, params);
		}
	int wrapCM = rout->getWrap();
	int wrap = rin->getWrap();

	pixCm = rout->pixels(0);
	pix = rin->pixels(0);
	for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(0, i);
			fill(rout, params);
		}
	pixCm = rout->pixels(0) + rout->getLx() - 1;
	pix = rin->pixels(0) + rin->getLx() - 1;
	for (int i = 0; i < rin->getLy(); i++, pixCm += wrapCM, pix += wrap)
		if (pixCm->getTone() == 255 && pixCm->getPaint() != 0 && pix->m == 0) {
			params.m_p = TPoint(rout->getLx() - 1, i);
			fill(rout, params);
		}
}