Пример #1
0
        /// <summary>
        /// Creates image from visible parts of tiles
        /// </summary>
        /// <param name="canvas">Bitmap to draw on</param>
        /// <param name="screenSize">Size of output window (picturebox)</param>
        /// <param name="tiles">Array of Tile objects</param>
        /// <param name="leftTopPointOfView">Left-top corner coordinates of the visible image</param>
        /// <returns></returns>       
        public Image DrawImage(int width, int height, Tile[] tiles, Point leftTopPointOfView, Size screenSize, bool highRes)
        {
           
            if (Scaler.ScaleFactor == 1)
            {
                _wrappers = ScaleNormal(tiles, leftTopPointOfView, screenSize);
            }
            else if (Scaler.ScaleFactor > 1)
            {
                _wrappers = ScaleUp(tiles, leftTopPointOfView, screenSize);
            }
            else
            {
                _wrappers = ScaleDown(tiles, leftTopPointOfView, screenSize, highRes);
            }

            return DrawWrappers(_wrappers, screenSize);
        }
Пример #2
0
        /// <summary>
        /// Returns image from visible tiles with 1:1 scale
        /// </summary>
        /// <param name="tiles"></param>
        /// <param name="leftTopPointOfView"></param>
        /// <param name="screenSize"></param>
        /// <returns></returns>
        private IEnumerable<TileRawWrapper> ScaleNormal(Tile[] tiles, Point leftTopPointOfView, Size screenSize)
        {
            var visibleTiles = tiles.Where(x => x.CheckVisibility(leftTopPointOfView,
                screenSize.Width, screenSize.Height));
            var tileImgWrappers = new List<TileRawWrapper>();

            foreach(var tile in visibleTiles)
            {
                var tileBytes = tile.ReadData();
                int xToScreen = tile.LeftTopCoord.X - leftTopPointOfView.X;
                int yToScreen = tile.LeftTopCoord.Y - leftTopPointOfView.Y;
                tileImgWrappers.Add(new TileRawWrapper(tileBytes, xToScreen, yToScreen, tile.Size.Width, tile.Size.Height));
            }

            return tileImgWrappers;
        }
Пример #3
0
        /// <summary>
        /// Returns image from visible tiles with scale factor < 1
        /// </summary>
        /// <param name="tiles"></param>
        /// <param name="leftTopPointOfView"></param>
        /// <param name="screenSize"></param>
        /// <param name="highRes">Determines if algorithm uses averaging to get downscaled image (true if it uses)</param>
        /// <returns></returns>
        private IEnumerable<TileRawWrapper> ScaleDown(Tile[] tiles, Point leftTopPointOfView, Size screenSize, bool highRes)
        {

            int scaledScreenX = (int)Math.Ceiling(screenSize.Width / Scaler.ScaleFactor);
            int scaledScreenY = (int)Math.Ceiling(screenSize.Height / Scaler.ScaleFactor);

            var visibleTiles = tiles.Where(x => x.CheckVisibility(leftTopPointOfView,
                scaledScreenX, scaledScreenY));

            int scale = (int)(1 / Scaler.ScaleFactor);
            int scalePower = (int)Math.Log(scale, 2);
            
            BlockingCollection<TileRawWrapper> tileImgWrappers = new BlockingCollection<TileRawWrapper>();

            //var tileImgWrappers = new List<TileImageWrapper>(visibleTiles.Count());

            Parallel.ForEach(visibleTiles, tile =>
            {
                byte[] imgData = tile.ReadData();
                byte[] sievedImage = new byte[imgData.Length >> scalePower >> scalePower];

                //scale by averaging nearby pixels
                int index = 0;

                for (int i = 0; i < tile.Size.Height * tile.Size.Width - tile.Size.Width; i += scale * tile.Size.Width)
                {
                    for (int j = i; j < i + tile.Size.Width; j += scale)
                    {
                        if (highRes)
                        {
                            int cumulative = 0;
                            for (int k = j; k < j + scale; k++)
                            {
                                cumulative += imgData[k];
                            }
                            sievedImage[index] = (byte)(cumulative >> scalePower);
                        }
                        else
                        {
                            sievedImage[index] = imgData[j];
                        }

                        index++;
                    }
                }

                var tw = new TileRawWrapper(sievedImage,
                    (int)((tile.LeftTopCoord.X - leftTopPointOfView.X) >> scalePower),
                    (int)((tile.LeftTopCoord.Y - leftTopPointOfView.Y) >> scalePower), 
                    tile.Size.Width >> scalePower, tile.Size.Height >> scalePower);

                tileImgWrappers.Add(tw);
            });

            return tileImgWrappers;
        }
Пример #4
0
        /// <summary>
        /// Returns image from visible tiles with scale factor > 1
        /// </summary>
        /// <param name="tiles"></param>
        /// <param name="leftTopPointOfView"></param>
        /// <param name="screenSize"></param>
        /// <returns></returns>
        private IEnumerable<TileRawWrapper> ScaleUp(Tile[] tiles, Point leftTopPointOfView, Size screenSize)
        {
            int scaledScreenX = (int)Math.Ceiling(screenSize.Width / Scaler.ScaleFactor);
            int scaledScreenY = (int)Math.Ceiling(screenSize.Height / Scaler.ScaleFactor);

            var visibleTiles = tiles.Where(x => x.CheckVisibility(leftTopPointOfView,
                scaledScreenX, scaledScreenY)).ToArray();

            BlockingCollection<TileRawWrapper> tileImgWrappers = new BlockingCollection<TileRawWrapper>();
            
            Size cropS = new Size();
            Tile leftTopTile = default(Tile);

            foreach(var tile in visibleTiles)
            {
                //stores relative offset by X for visible part from the beginning of the current tile
                int shiftTileX = (int)(leftTopPointOfView.X - tile.LeftTopCoord.X);
                shiftTileX = shiftTileX < 0 ? 0 : shiftTileX;

                //stores relative offset by Y for visible part from the beginning of the current tile
                int shiftTileY = (int)(leftTopPointOfView.Y - tile.LeftTopCoord.Y);
                shiftTileY = shiftTileY < 0 ? 0 : shiftTileY;

                //if not all scaled tile is visible we only take the visible part.
                int croppedWidth = tile.Size.Width - shiftTileX >= scaledScreenX ? scaledScreenX : tile.Size.Width - shiftTileX;
                int croppedHeight = tile.Size.Height - shiftTileY >= scaledScreenY ? scaledScreenY : tile.Size.Height - shiftTileY;

                var resizedW = (int)(croppedWidth * Scaler.ScaleFactor);
                var resizedH = (int)(croppedHeight * Scaler.ScaleFactor);

                var padding = (resizedW % 4);

                resizedW = resizedW + (padding == 0 ? 0 : 4 - padding);//bmp stride should be multiple of 4


                //determines resized canvas size
                Size resizedCanvasSize = new Size((int)(croppedWidth * Scaler.ScaleFactor), (int)(croppedHeight * Scaler.ScaleFactor));

                //take lefttop visible tile to measure offset for other tiles
                if (tile.Equals(visibleTiles.First()))
                {
                    leftTopTile = tile;
                    cropS = resizedCanvasSize;
                }

                //see pointToDraw description                    
                int x = tile.LeftTopCoord.X <= leftTopPointOfView.X ? 0 : cropS.Width +
                    ((tile.LeftTopCoord.X - leftTopTile.LeftTopCoord.X) / tile.Size.Width - 1) * tile.Size.Width * (int)Scaler.ScaleFactor;
                int y = tile.LeftTopCoord.Y <= leftTopPointOfView.Y ? 0 : cropS.Height +
                    ((tile.LeftTopCoord.Y - leftTopTile.LeftTopCoord.Y) / tile.Size.Height - 1) * tile.Size.Height * (int)Scaler.ScaleFactor;


                byte[] imgData = tile.ReadData();

                byte[] cropped = DrawingHelper.Crop(imgData, tile.Size.Width, shiftTileX, shiftTileY, croppedWidth, croppedHeight);

                byte[] resized = DrawingHelper.Resize(cropped, croppedWidth, resizedW, resizedH, Scaler.ScaleFactor);

                tileImgWrappers.Add(new TileRawWrapper(resized, x, y,
                    resizedCanvasSize.Width, resizedCanvasSize.Height));
            }


            return tileImgWrappers;
        }
Пример #5
0
 /// <summary>
 /// Draws visible tiles
 /// </summary>
 /// <param name="tiles">tile array</param>
 /// <param name="pointOfView">left top coordinate of visible area</param>
 /// <param name="highRes">Determines downscale resampling algorithm</param>
 /// <returns></returns>
 public Image Draw(Tile[] tiles, Point pointOfView, bool highRes = false)
 {
     _canvas = _tDrawer.DrawImage(_screenSize.Width, _screenSize.Height, tiles, pointOfView, _screenSize, highRes);
     return _canvas;
 }