/// <summary>
 /// Create a threshold halftone algorithm skeleton.
 /// </summary>
 /// <param name="thresholdFilter">Threshold filter</param>
 /// <param name="errorFilter">Error filter (optional)</param>
 /// <param name="scanningOrder">Scanning order</param>
 public ThresholdHalftoneMethod(
     ThresholdFilter thresholdFilter,
     ErrorFilter errorFilter,
     ScanningOrder scanningOrder
     )
 {
     ThresholdFilter = thresholdFilter;
     ErrorFilter = errorFilter;
     UseErrorFilter = errorFilter != null;
     ScanningOrder = scanningOrder;
 }
Exemple #2
0
        public static ErrorBuffer createFromScanningOrder(
            ScanningOrder scanningOrder,
            int height,
            int width)
        {
            // TODO: This is not quite nice. How to make it better?

            if (scanningOrder is ScanlineScanningOrder) {
                return new MatrixErrorBuffer(height, width);
            } else if (scanningOrder is SerpentineScanningOrder) {
                return new MatrixErrorBuffer(height, width)
                { SerpentineEnabled = true };
            } else if (scanningOrder is SFCScanningOrder) {
                return new VectorErrorBuffer(width);
            } else {
                return null;
            }
        }
Exemple #3
0
        public override void IterateSrcDestDirect(
            IterFuncSrcDest pixelFunc,
            ScanningOrder scanOrder)
        {
            //// TODO: it should be: PixelFetcher(_drawable, true) to support undo
            //// but for now it doesn't work
            //using (PixelFetcher pf = new PixelFetcher(_drawable, false)) {
            //    foreach (Coordinate<int> coords in scanFunc(Width, Height)) {
            //        int y = _rectangle.Y1 + coords.Y;
            //        int x = _rectangle.X1 + coords.X;
            //        pf[y, x] = pixelFunc(pf[y, x]);
            //    }
            //}
            //_drawable.Flush();
            ////_drawable.MergeShadow(true);
            //_drawable.Update(_rectangle);

            //foreach (Coordinate<int> coords in scanFunc(Width, Height)) {
            //    int y = _rectangle.Y1 + coords.Y;
            //    int x = _rectangle.X1 + coords.X;
            //    //if (y % 10 == 0) { Console.WriteLine("[y,x]: {0}, {1}", y, x); }
            //    putPixel(x, y, pixelFunc(getPixel(x, y)));
            //}

            initBuffer();

            // Note: getting coords using iterator or calling next() is almost
            // the same in speed, although using next() allows better handling
            // progess updates.

            int x = 0;
            int y = 0;

            //// loop with progress count using next()
            scanOrder.init(Width, Height);
            IEnumerator<Coordinate<int>> coordsEnum = scanOrder.getCoordsEnumerable().GetEnumerator();
            // calulate a reasonable progress update count
            int blockCount = Math.Max((int)Math.Ceiling(
                Math.Ceiling(Math.Sqrt(Width * Height)) / 10.0), 1);
            int blockSize = (int)Math.Ceiling(Height * Width / (double)blockCount);
            double progressPercentage = 0;
            double progressUnit = 1.0 / (double)blockCount;
            for (int i = 0; i < blockCount; i++) {
                for (int block = 0; block < blockSize; block++) {
                    //if (scanOrder.hasNext()) {
                    if (coordsEnum.MoveNext()) {
                        x = coordsEnum.Current.X;
                        y = coordsEnum.Current.Y;
                        //scanOrder.next();
                        //x = scanOrder.CurrentX;
                        //y = scanOrder.CurrentY;
                        setPixel(x, y, pixelFunc(getPixel(x, y)));
                    } else {
                        break;
                    }
                }
                progressPercentage += progressUnit;
                Progress.Update(progressPercentage);
            }

            //scanOrder.init(Width, Height);
            //int blockCount = 100;
            //int blockSize = Width * Height / blockCount;
            //double progressPercentage = 0;
            //double progressUnit = 1.0 / (double)blockCount;
            //int i = 0;
            //for (scanOrder.init(Width, Height); scanOrder.hasNext(); scanOrder.next(out x, out y)) {
            //    setPixel(x, y, pixelFunc(getPixel(x, y)));
            //    if ((i++ % blockSize) == 0) {
            //        progressPercentage += progressUnit;
            //        Progress.Update(progressPercentage);
            //    }
            //}

            // loop without progress count using next()
            //for (scanOrder.init(Width, Height); scanOrder.hasNext(); scanOrder.next(out x, out y)) {
            //    setPixel(x, y, pixelFunc(getPixel(x, y)));
            //}

            // loop without progress count using iterator
            //foreach (Coordinate<int> coords in scanOrder.getCoordsEnumerable(Width, Height)) {
            //    setPixel(coords.X, coords.Y, pixelFunc(getPixel(coords.X, coords.Y)));
            //}

            flushBuffer();

            //PixelRgn srcPR = new PixelRgn(_drawable, _rectangle, false, false);
            //PixelRgn destPR = new PixelRgn(_drawable, _rectangle, true, true);

            //foreach (Coordinate<int> coords in scanFunc(Width, Height)) {
            //    int y = _rectangle.Y1 + coords.Y;
            //    int x = _rectangle.X1 + coords.X;
            //    //rgn.GetPixel(px.Bytes, x, y);
            //    srcPR.GetPixel(byteBuf, x, y);
            //    px.Bytes = byteBuf;
            //    px.X = x; px.Y = y;
            //    px = pixelFunc(px);
            //    destPR.SetPixel(px.Bytes, x, y);
            //}
            //_drawable.Flush();
            //_drawable.MergeShadow(true);
            //_drawable.Update(_rectangle);
        }
Exemple #4
0
        public override void IterateSrcDestByRows(
            IterFuncSrcDest pixelFunc,
            ScanningOrder scanOrder)
        {
            //PixelRgn srcPR = new PixelRgn(_drawable, _rectangle, false, false);
            //PixelRgn destPR = new PixelRgn(_drawable, _rectangle, true, true);

            //_imageBuffer = new byte[_rectangle.Width * _rectangle.Height * _drawable.Bpp];

            initBuffer();

            int bufferIndexY = 0;
            int rowstride = _rectangle.Width * _drawable.Bpp;
            //byte[] row = new byte[rowstride];
            Pixel tmpPixel = new Pixel(_drawable.Bpp);
            byte[] pixelBytes = new byte[_drawable.Bpp];

            int blockCount = 100;
            double progressPercentage = 0;
            double progressUnit = (double)blockCount / (double)_rectangle.Height;

            for (int y = _rectangle.Y1; y < _rectangle.Y2;
                y++, bufferIndexY += rowstride)
            {
                //Array.Copy(_imageBuffer, bufferIndexY, row, 0, rowstride);
                //Pixel[] pixelRow = srcPR.GetRow(_rectangle.X1, y, _rectangle.Width);
                //Pixel[] row = srcPR.GetRow(_rectangle.X1, y, srcPR.W);
                for (int x = 0, bufferIndex = bufferIndexY; x < _rectangle.Width;
                    x++, bufferIndex += _drawable.Bpp)
                {
                    // setPixel(x, y, pixelFunc(pixelRow[x]));

                    tmpPixel.CopyFrom(_imageBuffer, bufferIndex);
                    tmpPixel.X = x; tmpPixel.Y = y;
                    tmpPixel = pixelFunc(tmpPixel);
                    tmpPixel.CopyTo(_imageBuffer, bufferIndex);
                }
                if ((y % blockCount) == 0) {
                    progressPercentage += progressUnit;
                    Progress.Update(progressPercentage);
                }
            }
            flushBuffer();

            //_drawable.Flush();
            //_drawable.MergeShadow(true);
            //_drawable.Update(_rectangle);
        }
Exemple #5
0
 /// <summary>
 /// Iterate over all image pixels with no explicit order and modify
 /// each pixel with given function.
 /// </summary>
 /// <param name="pixelFunc">Function to modify pixels</param>
 //public abstract void IterateSrcDestNoOrder(
 //    IterFuncSrcDest pixelFunc);
 /// <summary>
 /// Iterate over all image pixels using given scanning order
 /// and modify each pixel with given function. Use direct access
 /// to image pixels.
 /// </summary>
 /// <param name="pixelFunc">Function to modify pixels</param>
 /// <param name="scanOrder">Scanning order</param>
 public abstract void IterateSrcDestDirect(
     IterFuncSrcDest pixelFunc,
     ScanningOrder scanOrder);