Example #1
0
        /// <summary>
        /// For big images the scale that is just one step larger than the specified window will be used.
        /// </summary>
        /// <param name="envelope"></param>
        /// <param name="window"></param>
        /// <returns></returns>
        public override Bitmap GetBitmap(Extent envelope, Rectangle window)
        {
            if (window.Width == 0 || window.Height == 0) return null;
            if (_header == null) return null;
            if (_header.ImageHeaders == null) return null;
            if (_header.ImageHeaders[0] == null) return null;

            Rectangle expWindow = window.ExpandBy(1);
            IEnvelope expEnvelope = envelope.ToEnvelope().Reproportion(window, expWindow);

            IEnvelope env = expEnvelope.Intersection(Bounds.Extent.ToEnvelope());
            if (env == null || env.IsNull || env.Height == 0 || env.Width == 0) return null;

            PyramidImageHeader he = _header.ImageHeaders[0];
            int scale;

            double cwa = expWindow.Width / expEnvelope.Width;
            double cha = expWindow.Height / expEnvelope.Height;

            for (scale = 0; scale < _header.ImageHeaders.Length; scale++)
            {
                PyramidImageHeader ph = _header.ImageHeaders[scale];

                if (cwa > ph.NumColumns / Bounds.Width || cha > ph.NumRows / Bounds.Height)
                {
                    if (scale > 0) scale -= 1;
                    break;
                }
                he = ph;
            }

            RasterBounds overviewBounds = new RasterBounds(he.NumRows, he.NumColumns, he.Affine);
            Rectangle r = overviewBounds.CellsContainingExtent(envelope);
            if (r.Width == 0 || r.Height == 0) return null;
            byte[] vals = ReadWindow(r.Y, r.X, r.Height, r.Width, scale);
            Bitmap bmp = new Bitmap(r.Width, r.Height);
            BitmapData bData = bmp.LockBits(new Rectangle(0, 0, r.Width, r.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            Marshal.Copy(vals, 0, bData.Scan0, vals.Length);
            bmp.UnlockBits(bData);

            // Use the cell coordinates to determine the affine coefficients for the cells retrieved.
            double[] affine = new double[6];
            Array.Copy(he.Affine, affine, 6);
            affine[0] = affine[0] + r.X * affine[1] + r.Y * affine[2];
            affine[3] = affine[3] + r.X * affine[4] + r.Y * affine[5];

            if (window.Width == 0 || window.Height == 0)
            {
                return null;
            }

            Bitmap result = new Bitmap(window.Width, window.Height);
            Graphics g = Graphics.FromImage(result);

            //

            // Gets the scaling factor for converting from geographic to pixel coordinates
            double dx = (window.Width / envelope.Width);
            double dy = (window.Height / envelope.Height);

            double[] a = affine;

            // gets the affine scaling factors.
            float m11 = Convert.ToSingle(a[1] * dx);
            float m22 = Convert.ToSingle(a[5] * -dy);
            float m21 = Convert.ToSingle(a[2] * dx);
            float m12 = Convert.ToSingle(a[4] * -dy);
            float l = (float)(a[0] - .5 * (a[1] + a[2])); // Left of top left pixel
            float t = (float)(a[3] - .5 * (a[4] + a[5])); // top of top left pixel
            float xShift = (float)((l - envelope.MinX) * dx);
            float yShift = (float)((envelope.MaxY - t) * dy);
            g.Transform = new Matrix(m11, m12, m21, m22, xShift, yShift);
            g.PixelOffsetMode = PixelOffsetMode.Half;
            if (m11 > 1 || m22 > 1)
            {
                g.InterpolationMode = InterpolationMode.NearestNeighbor;
            }

            g.DrawImage(bmp, new PointF(0, 0));
            bmp.Dispose();
            g.Dispose();
            return result;
        }
        /// <summary>
        /// For big images the scale that is just one step larger than the specified window will be used.
        /// </summary>
        /// <param name="envelope"></param>
        /// <param name="window"></param>
        /// <returns></returns>
        public override Bitmap GetBitmap(IEnvelope envelope, Rectangle window)
        {
            if (window.Width == 0 || window.Height == 0) return null;
            if (_header == null) return null;
            if (_header.ImageHeaders == null) return null;
            if (_header.ImageHeaders[0] == null) return null;

            Rectangle expWindow = window.ExpandBy(1);
            IEnvelope expEnvelope = envelope.Reproportion(window, expWindow);
           


            IEnvelope env = expEnvelope.Intersection(Bounds.Envelope);
            if (env == null || env.IsNull || env.Height == 0 || env.Width == 0) return null;

            int fractionW = (int)((env.Width/expEnvelope.Width)*expWindow.Width);
            int fractionH = (int) ((env.Height/expEnvelope.Height)*expWindow.Height);

            PyramidImageHeader he = _header.ImageHeaders[0];
            int scale;
          
            double cwa = expWindow.Width/expEnvelope.Width;
            double cha = expWindow.Height/expEnvelope.Height;

            for(scale = 0; scale < _header.ImageHeaders.Length; scale++)
            {

                PyramidImageHeader ph = _header.ImageHeaders[scale];
               
                if(cwa > ph.NumColumns/Bounds.Width || cha > ph.NumRows/Bounds.Height)
                {
                    if(scale > 0)scale -= 1;
                    break;
                }
                he = ph;
            }

            // Get the cell coordinates of the part of the source bitmap to read
            int x = (int)((he.NumColumns / Bounds.Width) * (env.X - he.Affine[0]));
            int y = (int)((he.NumRows / Bounds.Height) * (he.Affine[3] - env.Y));
            int w = (int)((he.NumColumns / Bounds.Width) * env.Width);
            int h = (int)((he.NumRows / Bounds.Height) * env.Height);
            if (w == 0 || h == 0) return null;
            byte[] vals = ReadWindow(y, x, h, w, scale);
            Bitmap bmp = new Bitmap(w, h);
            BitmapData bData = bmp.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
            Marshal.Copy(vals, 0, bData.Scan0, vals.Length);
            bmp.UnlockBits(bData);

            // Use the cell coordinates to determine the affine coefficients for the cells retrieved.
            double[] affine = new double[6];
            Array.Copy(he.Affine, affine, 6);
            affine[0] = affine[0] + x*affine[1] + y*affine[2];
            affine[3] = affine[3] + x*affine[4] + y*affine[5];


            Bitmap result = new Bitmap(window.Width, window.Height);
            Graphics g = Graphics.FromImage(result);

            double imageToWorldW = affine[1];
            double imageToWorldH = affine[5];

            float cw = (float)(imageToWorldW * (window.Width / envelope.Width)); // cell width
            float ch = -(float)(imageToWorldH * (window.Height / envelope.Height)); // cell height
            //float sx = cw * (float)(_worldFile.Affine[2] / _worldFile.Affine[1]);
            //float sy = ch * (float)(_worldFile.Affine[4] / _worldFile.Affine[5]);
            const float sx = 0;
            const float sy = 0;
            float l = (float)(affine[0]);
            float t = (float)(affine[3]);
            float dx = (float)((l - envelope.Minimum.X) * (window.Width / envelope.Width));
            float dy = (float)((envelope.Maximum.Y - t) * (window.Height / envelope.Height));
            g.Transform = new Matrix(cw, sx, sy, ch, dx, dy);
            g.PixelOffsetMode = PixelOffsetMode.Half;
            if (cw > 1 || ch > 1) g.InterpolationMode = InterpolationMode.NearestNeighbor;
            g.DrawImage(bmp, new PointF(0, 0));
            bmp.Dispose();
            g.Dispose();
            return result;
        }