Beispiel #1
0
        public Bitmap GetNonRotatedPreview(Size size, Envelope bbox)
        {
            if (!IsValid)
            {
                return(null);
            }

            var geoTrans = (double[])_gt.Clone();

            // default transform
            if (DoublesAreEqual(geoTrans[0], 0) && DoublesAreEqual(geoTrans[3], 0))
            {
                geoTrans = new[] { 999.5, 1, 0, 1000.5, 0, -1 }
            }
            ;
            Bitmap     bitmap       = null;
            var        geoTransform = new GeoTransform(geoTrans);
            BitmapData bitmapData   = null;
            var        intVal       = new double[BandsNumber];

            const int iPixelSize = 3; //Format24bppRgb = byte[b,g,r]

            //check if image is in bounding box
            if ((bbox.MinX > _envelope.MaxX) || (bbox.MaxX < _envelope.MinX) || (bbox.MaxY < _envelope.MinY) || (bbox.MinY > _envelope.MaxY))
            {
                return(null);
            }

            double left   = Math.Max(bbox.MinX, _envelope.MinX);
            double top    = Math.Min(bbox.MaxY, _envelope.MaxY);
            double right  = Math.Min(bbox.MaxX, _envelope.MaxX);
            double bottom = Math.Max(bbox.MinY, _envelope.MinY);

            double x1           = Math.Abs(geoTransform.PixelX(left));
            double y1           = Math.Abs(geoTransform.PixelY(top));
            double imgPixWidth  = geoTransform.PixelXwidth(right - left);
            double imgPixHeight = geoTransform.PixelYwidth(bottom - top);

            //get screen pixels image should fill
            double dblBBoxW         = bbox.Width;
            double dblBBoxtoImgPixX = imgPixWidth / dblBBoxW;
            double dblImginMapW     = size.Width * dblBBoxtoImgPixX * geoTransform.HorizontalPixelResolution;

            double dblBBoxH         = bbox.Height;
            double dblBBoxtoImgPixY = imgPixHeight / dblBBoxH;
            double dblImginMapH     = size.Height * dblBBoxtoImgPixY * -geoTransform.VerticalPixelResolution;

            if ((DoublesAreEqual(dblImginMapH, 0)) || (DoublesAreEqual(dblImginMapW, 0)))
            {
                return(null);
            }

            //// ratios of bounding box to image ground space
            //double dblBBoxtoImgX = size.Width / dblBBoxW;
            //double dblBBoxtoImgY = size.Height / dblBBoxH;

            //double dblLocX = 0, dblLocY = 0;

            //// set where to display bitmap in Map
            //if (!DoublesAreEqual(bbox.MinX, left))
            //{
            //    if (!DoublesAreEqual(bbox.MaxX, right))
            //        dblLocX = (_envelope.MinX - bbox.MinX) * dblBBoxtoImgX;
            //    else
            //        dblLocX = size.Width - dblImginMapW;
            //}
            //if (!DoublesAreEqual(bbox.MaxY, top))
            //{
            //    if (!DoublesAreEqual(bbox.MinY, bottom))
            //        dblLocY = (bbox.MaxY - _envelope.MaxY) * dblBBoxtoImgY;
            //    else
            //        dblLocY = size.Height - dblImginMapH;
            //}

            double bitScalar = GetBitScalar();

            try
            {
                bitmap     = new Bitmap((int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), PixelFormat.Format24bppRgb);
                bitmapData = bitmap.LockBits(new Rectangle(0, 0, (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH)), ImageLockMode.ReadWrite, bitmap.PixelFormat);

                byte cr = NoDataInitColor.R;
                byte cg = NoDataInitColor.G;
                byte cb = NoDataInitColor.B;

                var noDataValues = new double[BandsNumber];
                var scales       = new double[BandsNumber];

                ColorTable colorTable = null;
                unsafe
                {
                    var buffer = new double[BandsNumber][];
                    var band   = new Band[BandsNumber];
                    var ch     = new int[BandsNumber];
                    // get data from image
                    for (int i = 0; i < BandsNumber; i++)
                    {
                        buffer[i] = new double[(int)Math.Round(dblImginMapW) * (int)Math.Round(dblImginMapH)];
                        band[i]   = _ds.GetRasterBand(i + 1);

                        //get nodata value if present
                        Int32 hasVal;
                        band[i].GetNoDataValue(out noDataValues[i], out hasVal);
                        if (hasVal == 0)
                        {
                            noDataValues[i] = Double.NaN;
                        }
                        band[i].GetScale(out scales[i], out hasVal);
                        if (hasVal == 0)
                        {
                            scales[i] = 1.0;
                        }

                        band[i].ReadRaster((int)Math.Round(x1), (int)Math.Round(y1), (int)Math.Round(imgPixWidth),
                                           (int)Math.Round(imgPixHeight),
                                           buffer[i], (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH),
                                           0, 0);

                        switch (band[i].GetRasterColorInterpretation())
                        {
                        case ColorInterp.GCI_BlueBand:
                            ch[i] = 0;
                            break;

                        case ColorInterp.GCI_GreenBand:
                            ch[i] = 1;
                            break;

                        case ColorInterp.GCI_RedBand:
                            ch[i] = 2;
                            break;

                        case ColorInterp.GCI_Undefined:
                            if (BandsNumber > 1)
                            {
                                ch[i] = 3;     // infrared
                            }
                            else
                            {
                                ch[i] = 4;
                                if (ColorBlend == null)
                                {
                                    Double dblMin, dblMax;
                                    band[i].GetMinimum(out dblMin, out hasVal);
                                    if (hasVal == 0)
                                    {
                                        dblMin = Double.NaN;
                                    }
                                    band[i].GetMaximum(out dblMax, out hasVal);
                                    if (hasVal == 0)
                                    {
                                        dblMax = double.NaN;
                                    }
                                    if (Double.IsNaN(dblMin) || Double.IsNaN(dblMax))
                                    {
                                        double dblMean, dblStdDev;
                                        band[i].GetStatistics(0, 1, out dblMin, out dblMax, out dblMean, out dblStdDev);
                                        //double dblRange = dblMax - dblMin;
                                        //dblMin -= 0.1*dblRange;
                                        //dblMax += 0.1*dblRange;
                                    }
                                    var minmax = new float[] { Convert.ToSingle(dblMin), 0.5f * Convert.ToSingle(dblMin + dblMax), Convert.ToSingle(dblMax) };
                                    var colors = new Color[] { Color.Blue, Color.Yellow, Color.Red };
                                    ColorBlend = new ColorBlend(colors, minmax);
                                }
                                intVal = new Double[3];
                            }
                            break;

                        case ColorInterp.GCI_GrayIndex:
                            ch[i] = 0;
                            break;

                        case ColorInterp.GCI_PaletteIndex:
                            colorTable = band[i].GetRasterColorTable();
                            ch[i]      = 5;
                            intVal     = new Double[3];
                            break;

                        default:
                            ch[i] = -1;
                            break;
                        }
                    }

                    if (BitDepth == 32)
                    {
                        ch = new[] { 0, 1, 2 }
                    }
                    ;

                    int pIndx = 0;
                    for (int y = 0; y < Math.Round(dblImginMapH); y++)
                    {
                        byte *row = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride);
                        for (int x = 0; x < Math.Round(dblImginMapW); x++, pIndx++)
                        {
                            for (int i = 0; i < BandsNumber; i++)
                            {
                                intVal[i] = buffer[i][pIndx] / bitScalar;
                                Double imageVal = intVal[i] = intVal[i] / bitScalar;
                                if (ch[i] == 4)
                                {
                                    if (!DoublesAreEqual(imageVal, noDataValues[i]))
                                    {
                                        Color color = ColorBlend.GetColor(Convert.ToSingle(imageVal));
                                        intVal[0] = color.B;
                                        intVal[1] = color.G;
                                        intVal[2] = color.R;
                                        //intVal[3] = ce.c4;
                                    }
                                    else
                                    {
                                        intVal[0] = cb;
                                        intVal[1] = cg;
                                        intVal[2] = cr;
                                    }
                                }
                                else if (ch[i] == 5 && colorTable != null)
                                {
                                    if (!DoublesAreEqual(imageVal, noDataValues[i]))
                                    {
                                        ColorEntry ce = colorTable.GetColorEntry(Convert.ToInt32(imageVal));
                                        intVal[0] = ce.c3;
                                        intVal[1] = ce.c2;
                                        intVal[2] = ce.c1;
                                        //intVal[3] = ce.c4;
                                    }
                                    else
                                    {
                                        intVal[0] = cb;
                                        intVal[1] = cg;
                                        intVal[2] = cr;
                                    }
                                }
                                else
                                {
                                    if (ColorCorrect)
                                    {
                                        // TODO
                                        // intVal[i] = ApplyColorCorrection(intVal[i], 0, ch[i], 0, 0);
                                    }
                                }

                                if (intVal[i] > 255)
                                {
                                    intVal[i] = 255;
                                }
                            }

                            WritePixel(x, intVal, iPixelSize, ch, row);
                        }
                    }
                }
            }
            catch
            {
                return(null);
            }
            finally
            {
                if (bitmapData != null)
                {
                    bitmap.UnlockBits(bitmapData);
                }
            }

            if (TransparentColor != Color.Empty)
            {
                bitmap.MakeTransparent(TransparentColor);
            }
            //g.DrawImage(bitmap, new Point((int)Math.Round(dblLocX), (int)Math.Round(dblLocY)));
            return(bitmap);
        }

        #endregion IImage Members
    }