/// <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; }