コード例 #1
0
ファイル: ImgUtil.cs プロジェクト: MALORGIS/TileToImage
        }//end method

        /// <summary>
        /// 画像出力
        /// </summary>
        /// <param name="tileUtil"></param>
        /// <returns></returns>
        public ExportResult Export(Extent ext, int level)
        {
            var tileUtil = this._tileUtil;

            var infos = tileUtil.ExtentToTileInfo(level, ext);
            var size  = tileUtil.CalcPxSize(level, ext);

            this._infos = infos;
            this._size  = size;

            PixelFormat  pxFormat = PixelFormat.Format32bppArgb;
            ColorPalette palette  = null;

            //一旦最初の画像を取ってピクセルフォーマットを取得
            using (WebClient client = new WebClient())
                using (var mem = new MemoryStream(client.DownloadData(infos.FirstOrDefault().Url)))
                    using (var tile = Bitmap.FromStream(mem))
                    {
                        pxFormat = tile.PixelFormat;
                        palette  = tile.Palette;
                    }//end io
            //インデックス系だとGraphicsが動作しないので仕方なし
            //インデックス系を扱う場合はExportIndexを使用
            if (pxFormat == PixelFormat.Indexed || pxFormat == PixelFormat.Format8bppIndexed)
            {
                pxFormat = PixelFormat.Format32bppArgb;
            }

            var img = new Bitmap(size.Width, size.Height, pxFormat);

            using (var gra = Graphics.FromImage(img))
            {
                var esriWorldFile = this.exportImage(ext, (tileParam) => {
                    var tile = tileParam.Tile;
                    var x    = tileParam.X;
                    var y    = tileParam.Y;
                    gra.DrawImageUnscaled(tile, x, y);
                });
                return(new ExportResult(img, esriWorldFile));
            } //end graphics
        }     //end method
コード例 #2
0
ファイル: ImgUtil.cs プロジェクト: MALORGIS/TileToImage
        }     //end method

        /// <summary>
        /// インデックスカラー画像の出力
        /// </summary>
        /// <param name="ext"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        public ExportResult Export8bppIndexed(Extent ext, int level)
        {
            var tileUtil = this._tileUtil;
            var infos    = tileUtil.ExtentToTileInfo(level, ext);
            var size     = tileUtil.CalcPxSize(level, ext);

            this._infos = infos;
            this._size  = size;


            PixelFormat  pxFormat = PixelFormat.Format8bppIndexed;
            ColorPalette palette  = null;

            //一旦最初の画像を取ってピクセルフォーマットを取得
            using (WebClient client = new WebClient())
                using (var mem = new MemoryStream(client.DownloadData(infos.FirstOrDefault().Url)))
                    using (var tile = Bitmap.FromStream(mem))
                    {
                        pxFormat = tile.PixelFormat;
                        palette  = tile.Palette;
                    }//end io

            //パレットにセットするための色のリストを準備
            List <Color> colors = null;

            if (this.Colors == null)
            {
                colors      = new List <Color>(palette.Entries);
                this.Colors = colors;
            }
            else
            {
                colors = new List <Color>(this.Colors);
            }//end if


            //返却画像の用意
            var    img           = new Bitmap(size.Width, size.Height, PixelFormat.Format8bppIndexed);
            string esriWorldFile = null;

            try
            {
                //ロックする
                var data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.WriteOnly, img.PixelFormat);

                //バイト配列の取得
                var bytes = new byte[data.Height * data.Stride];
                Marshal.Copy(data.Scan0, bytes, 0, bytes.Length);


                esriWorldFile = this.exportImage(ext, (tileParams) =>
                {
                    var tile = tileParams.Tile;
                    var x    = tileParams.X;
                    var y    = tileParams.Y;

                    //全体サイズよりXYがでかい場合戻す
                    if (size.Width < x)//(size.Height < y || size.Width < x)
                    {
                        return;
                    }

                    try
                    {
                        var pal = tile.Palette;
                        Dictionary <int, int> colorMap = new Dictionary <int, int>();


                        //Debug.WriteLine("---------------------------------------------");
                        for (int i = 0; i < pal.Entries.Length; i++)
                        {
                            var c = pal.Entries[i];
                            //Debug.WriteLine($"{i}:RGB:{String.Format("#{0:X2}{1:X2}{2:X2}", c.R, c.G, c.B)}");

                            var colorIndex = colors.IndexOf(c);
                            //ない場合
                            if (colorIndex < 0)
                            {
                                colorMap.Add(i, colors.Count);
                                colors.Add(c);
                            }
                            else
                            {
                                colorMap.Add(i, colorIndex);
                            } //end if
                        }     //end loop
                         //Debug.WriteLine("---------------------------------------------");

                        var tw = tile.Width;
                        var th = tile.Height;

                        //はみ出た分を切るよう
                        var tileX = x < 0 ? Math.Abs(x) : 0;
                        var tileY = y < 0 ? Math.Abs(y) : 0;

                        var tileW = size.Width < x + tw ? tw - ((x + tw) - size.Width) : tw;
                        var tileH = size.Height < y + th ?th - ((y + th) - size.Height) : th;

                        //はみ出ているばあいはけずる
                        tileW = tileW - tileX;
                        tileH = tileH - tileY;

                        //ロックする
                        try
                        {
                            //タイルデータの取得
                            var tileBytes = this.getTileData(tile, colorMap, colors);
                            var tstride   = tw;


                            //幅単位で回る
                            //for (int i = 0; i < tiledata.Width; i++)

                            //タイルから転送先画像のインデックスを足すよう
                            var cnt  = 0;
                            var setX = x < 0 ? 0 : x;
                            var setY = y < 0 ? 0 : y;

                            for (int i = tileY; i < tileY + tileH; i++)
                            {
                                var start = i * tstride + tileX;

                                //var start = i * tiledata.Height;
                                //var copyBytes = new byte[1 * tiledata.Height];
                                var copyBytes = new byte[1 * tileW];

                                var imgStart = (setY + cnt) * data.Stride + setX;
                                cnt++;

                                try
                                {
                                    Array.Copy(tileBytes, start, copyBytes, 0, copyBytes.Length);
                                    Array.Copy(copyBytes, 0, bytes, imgStart, copyBytes.Length);
                                }
                                catch (Exception ex)
                                {
                                    Console.Error.WriteLine(ex.Message);
                                    Console.Error.WriteLine(ex.StackTrace);
                                    Console.Error.WriteLine($"Start:{start} Length:{copyBytes.Length}");
                                    Console.Error.WriteLine($"image:{imgStart}");
                                }
                            }

                            ////アンロック
                            //tile.UnlockBits(tiledata);
                        }
                        catch (Exception ex)
                        {
                            Console.Error.WriteLine(ex.Message);
                            Console.Error.WriteLine(ex.StackTrace);
                            Console.Error.WriteLine($"TH:{tileH} TW:{tileW} X:{tileX} Y:{tileY}");
                        }
                    }catch (Exception ex)
                    {
                        Console.Error.WriteLine(ex.Message);
                        Console.Error.WriteLine(ex.StackTrace);
                    }
                });//end tile action

                var newPalette = img.Palette;
                //色数が多い際は切り捨て
                var colorCount = colors.Count;
                if (newPalette.Entries.Length < colors.Count)
                {
                    Console.WriteLine("color over");
                    colorCount = newPalette.Entries.Length;
                }

                Array.Copy(colors.ToArray(), newPalette.Entries, colorCount);
                img.Palette = newPalette;



                //バイト配列の書き込み
                Marshal.Copy(bytes, 0, data.Scan0, bytes.Length);

                img.UnlockBits(data);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
                Debug.Print(ex.StackTrace);

                if (img != null)
                {
                    img.Dispose();
                    img = null;
                }
                throw;
            } //end try
            return(new ExportResult(img, esriWorldFile));
        }     //end method