예제 #1
0
        public async virtual Task <MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
        {
            MemoryImage?image = null;

            try
            {
                using var response = await http.GetAsync(this.ThumbnailImageUrl, cancellationToken)
                                     .ConfigureAwait(false);

                response.EnsureSuccessStatusCode();

                using var imageStream = await response.Content.ReadAsStreamAsync()
                                        .ConfigureAwait(false);

                image = await MemoryImage.CopyFromStreamAsync(imageStream)
                        .ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();

                return(image);
            }
            catch (OperationCanceledException)
            {
                image?.Dispose();
                throw;
            }
        }
        /// <summary>
        /// Release all resources used by this <see cref="DoubleBufferedGraphics"/>.
        /// </summary>
        public void Dispose()
        {
            if (MemoryImage != null)
            {
                MemoryImage.Dispose();
                MemoryImage = null;
            }

            if (Graphics != null)
            {
                Graphics.Dispose();
                Graphics = null;
            }
        }
예제 #3
0
        /// <summary>指定されたタイル番号のタイル画像を読み込むメソッド</summary>
        private async Task <MemoryImage> LoadTileImageAsync(HttpClient http, Point pos)
        {
            var tileUrl = TileServerBase + $"/{this.Zoom}/{pos.X}/{pos.Y}.png";

            using (var stream = await http.GetStreamAsync(tileUrl).ConfigureAwait(false))
            {
                MemoryImage result = null;
                try
                {
                    result = await MemoryImage.CopyFromStreamAsync(stream).ConfigureAwait(false);

                    return(result);
                }
                catch { result?.Dispose(); throw; }
            }
        }
        /// <summary>
        /// Reset this <see cref="DoubleBufferedGraphics"/>.
        /// </summary>
        public void Reset()
        {
            if (MemoryImage != null)
            {
                MemoryImage.Dispose();
                MemoryImage = null;
            }

            if (Graphics != null)
            {
                Graphics.Dispose();
                Graphics = null;
            }

            MemoryImage = new Bitmap(Size.Width, Size.Height);
            Graphics    = Graphics.FromImage(MemoryImage);
        }
        /// <summary>
        /// This method is the preferred method of drawing a background image.
        /// It is *MUCH* faster than any of the Graphics.DrawImage() methods.
        /// Warning: The memory image and the <see cref="System.Drawing.Graphics"/> object
        /// will be reset after calling this method. This should be your first
        /// drawing operation.
        /// </summary>
        /// <param name="image">The image to draw.</param>
        public void SetBackgroundImage(Image image)
        {
            if (MemoryImage != null)
            {
                MemoryImage.Dispose();
                MemoryImage = null;
            }

            if (Graphics != null)
            {
                Graphics.Dispose();
                Graphics = null;
            }

            MemoryImage = image.Clone() as Image;

            if (MemoryImage != null)
            {
                Graphics = Graphics.FromImage(MemoryImage);
            }
        }
예제 #6
0
        public override async Task <MemoryImage> LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken)
        {
            // 画像中央に描画されるタイル (ピクセル単位ではなくタイル番号を表す)
            // タイル番号に小数部が含まれているが、これはタイル内の相対的な位置を表すためこのまま保持する
            var centerTileNum = this.WorldToTilePos(this.Longitude, this.Latitude, this.Zoom);

            // 画像左上に描画されるタイル
            var topLeftTileNum = PointF.Add(centerTileNum, new SizeF(-this.ThumbnailSize.Width / 2.0f / TileSize.Width, -this.ThumbnailSize.Height / 2.0f / TileSize.Height));

            // タイル番号の小数部をもとに、タイル画像を描画する際のピクセル単位のオフセットを算出する
            var tileOffset = Size.Round(new SizeF(-TileSize.Width * (topLeftTileNum.X - (int)topLeftTileNum.X), -TileSize.Height * (topLeftTileNum.Y - (int)topLeftTileNum.Y)));

            // 縦横のタイル枚数
            var tileCountX = (int)Math.Ceiling((double)(this.ThumbnailSize.Width + Math.Abs(tileOffset.Width)) / TileSize.Width);
            var tileCountY = (int)Math.Ceiling((double)(this.ThumbnailSize.Height + Math.Abs(tileOffset.Height)) / TileSize.Height);

            // 読み込む対象となるタイル画像が 10 枚を越えていたら中断
            // ex. 一辺が 512px 以内のサムネイル画像を生成する場合、必要なタイル画像は最大で 9 枚
            if (tileCountX * tileCountY > 10)
            {
                throw new OperationCanceledException();
            }

            // タイル画像を読み込む
            var tilesTask = new Task <MemoryImage> [tileCountX, tileCountY];

            foreach (var x in Enumerable.Range(0, tileCountX))
            {
                foreach (var y in Enumerable.Range(0, tileCountY))
                {
                    var tilePos = Point.Add(Point.Truncate(topLeftTileNum), new Size(x, y));
                    tilesTask[x, y] = this.LoadTileImageAsync(http, tilePos);
                }
            }

            await Task.WhenAll(tilesTask.Cast <Task <MemoryImage> >())
            .ConfigureAwait(false);

            using (var bitmap = new Bitmap(this.ThumbnailSize.Width, this.ThumbnailSize.Height))
            {
                using (var g = Graphics.FromImage(bitmap))
                {
                    g.TranslateTransform(tileOffset.Width, tileOffset.Height);

                    foreach (var x in Enumerable.Range(0, tileCountX))
                    {
                        foreach (var y in Enumerable.Range(0, tileCountY))
                        {
                            using (var image = tilesTask[x, y].Result)
                            {
                                g.DrawImage(image.Image, TileSize.Width * x, TileSize.Height * y);
                            }
                        }
                    }
                }

                MemoryImage result = null;
                try
                {
                    result = MemoryImage.CopyFromImage(bitmap);
                    return(result);
                }
                catch { result?.Dispose(); throw; }
            }
        }