Example #1
0
 public static void SaveColorToBMP(string filePath, Microsoft.Psi.Imaging.Image rgbImage)
 {
     using (FileStream fs = new FileStream(filePath, FileMode.Create))
     {
         BitmapFileHeader header     = default(BitmapFileHeader);
         BitmapInfoHeader infoheader = default(BitmapInfoHeader);
         header.Type = 0x4d42;
         int headerSize = Marshal.SizeOf(header);
         int infoSize   = Marshal.SizeOf(infoheader);
         header.OffBits   = Marshal.SizeOf(header) + Marshal.SizeOf(infoheader);
         header.Size      = header.OffBits + 3 * rgbImage.Width * rgbImage.Height;
         header.Reserved1 = 0;
         header.Reserved2 = 0;
         byte[] bufferHeader = StructAsByteArray(header);
         fs.Write(bufferHeader, 0, bufferHeader.Length);
         infoheader.Size          = Marshal.SizeOf(infoheader);
         infoheader.Width         = rgbImage.Width;
         infoheader.Height        = rgbImage.Height;
         infoheader.Planes        = 1;
         infoheader.BitCount      = 24;
         infoheader.Compression   = 0; // Uncompressed
         infoheader.SizeImage     = rgbImage.Width * rgbImage.Height * 3;
         infoheader.XPelsPerMeter = 96;
         infoheader.YPelsPerMeter = 96;
         infoheader.ClrUsed       = 0;
         infoheader.ClrImportant  = 0;
         byte[] bufferInfoHeader = StructAsByteArray(infoheader);
         fs.Write(bufferInfoHeader, 0, bufferInfoHeader.Length);
         byte[] imageData = new byte[infoheader.SizeImage];
         Marshal.Copy(rgbImage.ImageData, imageData, 0, infoheader.SizeImage);
         fs.Write(imageData, 0, infoheader.SizeImage);
     }
 }
Example #2
0
        public BitmapWriter(Stream stream, int width, int height)
            : base(stream)
        {
            _width  = width;
            _height = height;
            var fileSize = width * height * 4 + 14 + 40;

            _bitmapFileHeader = new BitmapFileHeader((uint)fileSize, 14 + 40);
            _bitmapInfoHeader = new BitmapInfoHeader(width, -height);
            WriteHeader();
        }
Example #3
0
        private BitmapFileHeader ReadBitmapFileHeader(BinaryReader br)
        {
            BitmapFileHeader BFH = new BitmapFileHeader();

            BFH.type      = br.ReadUInt16();
            BFH.size      = br.ReadUInt32();
            BFH.reserved1 = br.ReadUInt16();
            BFH.reserved2 = br.ReadUInt16();
            BFH.offBits   = br.ReadUInt32();

            return(BFH);
        }
Example #4
0
        /// <summary>
        /// the DIB readed should solve the issue reported here: https://sourceforge.net/projects/greenshot/forums/forum/676083/topic/6354353/index/page/1
        /// </summary>
        /// <returns>Image</returns>
        private static Image GetDIBImage(IDataObject dataObejct)
        {
            try {
                // If the EnableSpecialDIBClipboardReader flag in the config is set, use the code from:
                // http://www.thomaslevesque.com/2009/02/05/wpf-paste-an-image-from-the-clipboard/
                // to read the DeviceIndependentBitmap from the clipboard, this might fix bug 3576125
                if (config.EnableSpecialDIBClipboardReader)
                {
                    MemoryStream dibStream = GetFromDataObject(dataObejct, DataFormats.Dib) as MemoryStream;
                    if (isValidStream(dibStream))
                    {
                        LOG.Info("Found valid DIB stream, trying to process it.");
                        byte[] dibBuffer = new byte[dibStream.Length];
                        dibStream.Read(dibBuffer, 0, dibBuffer.Length);
                        BitmapInfoHeader infoHeader = BinaryStructHelper.FromByteArray <BitmapInfoHeader>(dibBuffer);
                        LOG.InfoFormat("Using special DIB format reader for biCompression {0}", infoHeader.biCompression);
                        int  fileHeaderSize = Marshal.SizeOf(typeof(BitmapFileHeader));
                        uint infoHeaderSize = infoHeader.biSize;
                        int  fileSize       = (int)(fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage);

                        BitmapFileHeader fileHeader = new BitmapFileHeader();
                        fileHeader.bfType      = BitmapFileHeader.BM;
                        fileHeader.bfSize      = fileSize;
                        fileHeader.bfReserved1 = 0;
                        fileHeader.bfReserved2 = 0;
                        fileHeader.bfOffBits   = (int)(fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4);

                        byte[] fileHeaderBytes = BinaryStructHelper.ToByteArray <BitmapFileHeader>(fileHeader);

                        using (MemoryStream bitmapStream = new MemoryStream()) {
                            bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
                            bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
                            bitmapStream.Seek(0, SeekOrigin.Begin);
                            using (Image tmpImage = Image.FromStream(bitmapStream)) {
                                if (tmpImage != null)
                                {
                                    return(ImageHelper.Clone(tmpImage));
                                }
                            }
                        }
                    }
                }
                else
                {
                    LOG.Info("Skipping special DIB format reader as it's disabled in the configuration.");
                }
            } catch (Exception dibEx) {
                LOG.Error("Problem retrieving DIB from clipboard.", dibEx);
            }
            return(null);
        }
Example #5
0
        /// <summary>
        ///     An existing bitmap file.
        /// </summary>
        /// <param name="filename">A file in a .bmp format.</param>
        public BitmapFile(string filename) {
            var data = File.ReadAllBytes(filename);

            var pFileHeaderData = Marshal.AllocHGlobal(Marshal.SizeOf(_header));
            try {
                Marshal.Copy(data, 0, pFileHeaderData, Marshal.SizeOf(_header));
                _header = (BitmapFileHeader)Marshal.PtrToStructure(pFileHeaderData, typeof (BitmapFileHeader));
            } finally {
                Marshal.FreeHGlobal(pFileHeaderData);
            }

            var size = data.Length - Marshal.SizeOf(_header);
            var bitmapData = new byte[size];
            Buffer.BlockCopy(data, Marshal.SizeOf(_header), bitmapData, 0, size);
            _bitmap = new DeviceIndependentBitmap(bitmapData);
        }
Example #6
0
        private void _checkResource(string res, List <ValidationErrorView> errors, ReadableTuple <int> tuple, HashSet <string> processed, ValidationErrors error, string type, ServerDbs serverDb, List <GrfImageType> allowedTypes)
        {
            if (processed.Add(res))
            {
                var result = _database.MetaGrf.GetData(res);

                if (result == null)
                {
                    errors.Add(new ResourceError(error, tuple.Key, type + ": " + res, serverDb, this, res));
                }
                else
                {
                    if (SdeAppConfiguration.VaResInvalidFormat)
                    {
                        GrfImage image = new GrfImage(result);

                        foreach (var imType in allowedTypes)
                        {
                            if (image.GrfImageType == imType)
                            {
                                if (imType == GrfImageType.Bgr24)
                                {
                                    BitmapFileHeader bitmap = new BitmapFileHeader(new ByteReader(result));

                                    if (bitmap.DibHeader.ColorTableUsed != 0 || bitmap.DibHeader.ColorTableImportant != 0)
                                    {
                                        errors.Add(new ResourceError(ValidationErrors.ResInvalidType, tuple.Key, "SuspiciousImageFormat: " + res, serverDb, this, res)
                                        {
                                            ImageType = imType
                                        });
                                        return;
                                    }
                                }

                                return;
                            }
                        }

                        errors.Add(new ResourceError(ValidationErrors.ResInvalidType, tuple.Key, "ImageType: " + res, serverDb, this, res)
                        {
                            ImageType = allowedTypes[0]
                        });
                    }
                }
            }
        }
Example #7
0
    public void Save(string filename)
    {
        const byte BYTES_PER_PIXEL = 3;
        int        row_increment_  = width * BYTES_PER_PIXEL;

        using (FileStream stream = File.Create(filename))
        {
            BitmapInformationHeader bih = new BitmapInformationHeader();
            bih.width            = (uint)width;
            bih.height           = (uint)height;
            bih.bit_count        = BYTES_PER_PIXEL << 3;
            bih.clr_important    = 0;
            bih.clr_used         = 0;
            bih.compression      = 0;
            bih.planes           = 1;
            bih.size             = (uint)Marshal.SizeOf(bih);
            bih.x_pels_per_meter = 0;
            bih.y_pels_per_meter = 0;
            bih.size_image       = (((bih.width * BYTES_PER_PIXEL) + 3) & 0x0000FFFC) * bih.height;

            BitmapFileHeader bfh = new BitmapFileHeader();
            bfh.type      = 19778;
            bfh.size      = (uint)(Marshal.SizeOf(bfh) + Marshal.SizeOf(bih) + bih.size_image);
            bfh.reserved1 = 0;
            bfh.reserved2 = 0;
            bfh.off_bits  = (uint)(Marshal.SizeOf(bih) + Marshal.SizeOf(bfh));

            stream.Write(GetBytes(bfh), 0, Marshal.SizeOf(bfh));
            stream.Write(GetBytes(bih), 0, Marshal.SizeOf(bih));

            int    padding      = (4 - ((3 * width) % 4)) % 4;
            byte[] padding_data = { 0x00, 0x00, 0x00, 0x00 };

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    Color32 c   = buffer[y * width + x];
                    byte[]  bgr = { c.b, c.g, c.r };
                    stream.Write(bgr, 0, 3);
                }
                stream.Write(padding_data, 0, padding);
            }
        }
    }
Example #8
0
        /// <summary>
        ///     An existing bitmap file.
        /// </summary>
        /// <param name="filename">A file in a .bmp format.</param>
        public BitmapFile(string filename)
        {
            var data = File.ReadAllBytes(filename);

            var pFileHeaderData = Marshal.AllocHGlobal(Marshal.SizeOf(_header));

            try {
                Marshal.Copy(data, 0, pFileHeaderData, Marshal.SizeOf(_header));
                _header = (BitmapFileHeader)Marshal.PtrToStructure(pFileHeaderData, typeof(BitmapFileHeader));
            } finally {
                Marshal.FreeHGlobal(pFileHeaderData);
            }

            var size       = data.Length - Marshal.SizeOf(_header);
            var bitmapData = new byte[size];

            Buffer.BlockCopy(data, Marshal.SizeOf(_header), bitmapData, 0, size);
            _bitmap = new DeviceIndependentBitmap(bitmapData);
        }
Example #9
0
        static unsafe byte[] MakeBitmapFileHeader(ulong fileSize)
        {
            var header = new BitmapFileHeader
            {
                bfType = 0x4D42,
                bfSize = fileSize,
                //bfReserved1 = 0,
                //bfReserved2 = 0,
                bfOffBits = 54,
            };

            const int size  = 14;
            var       bytes = new byte[size];

            fixed(byte *pbytes = bytes)
            {
                *(BitmapFileHeader *)pbytes = header;
            }

            return(bytes);
        }
Example #10
0
        public void Save(string filename)
        {
            if (string.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException(nameof(filename));
            }
            if (disposedValue)
            {
                throw new ObjectDisposedException(nameof(FastBitmap));
            }

            int sizeOfFileHeader = sizeof(BitmapFileHeader);
            int sizeOfInfoHeader = sizeof(BitmapInfoHeader);
            int dibSectionLength = (Width * Height) * 3;

            int realInfoHeaderSize = Marshal.ReadInt32(_bitmapInfoHeader);

            if (realInfoHeaderSize != 0 && sizeOfInfoHeader != realInfoHeaderSize)
            {
                sizeOfInfoHeader = realInfoHeaderSize;
            }

            BitmapFileHeader fileHeader = new BitmapFileHeader
            {
                OffsetBits = (uint)(sizeOfFileHeader + sizeOfInfoHeader),
                Size       = (uint)(dibSectionLength + sizeOfFileHeader + sizeOfInfoHeader),
                Type       = 0x4D42
            };

            byte[] bitmap = new byte[sizeOfFileHeader + sizeOfInfoHeader + dibSectionLength];

            Marshal.Copy((IntPtr)(void *)&fileHeader, bitmap, 0, sizeOfFileHeader);
            Marshal.Copy(_bitmapInfoHeader, bitmap, sizeOfFileHeader, sizeOfInfoHeader);
            Marshal.Copy(_dibSection, bitmap, sizeOfFileHeader + sizeOfInfoHeader, dibSectionLength);

            File.WriteAllBytes(filename, bitmap);
        }
        /// <summary>
        /// Get a DIB from the Clipboard
        /// </summary>
        /// <param name="clipboardAccessToken"></param>
        /// <returns>Bitmap or null</returns>
        public static Bitmap GetAsDeviceIndependendBitmap(this IClipboardAccessToken clipboardAccessToken)
        {
            var formats = clipboardAccessToken.AvailableFormats().ToList();

            if (!formats.Contains(StandardClipboardFormats.Bitmap.AsString()))
            {
                return(null);
            }

            var format17Bytes = clipboardAccessToken.GetAsBytes(StandardClipboardFormats.Bitmap.AsString());
            var infoHeader    = BinaryStructHelper.FromByteArray <BitmapInfoHeader>(format17Bytes);

            if (infoHeader.IsDibV5)
            {
                Log.Warn().WriteLine("Getting DIBV5 (format 17) when requesting DIB");
                return(null);
            }

            // Bitmap version older than 5
            var fileHeaderSize  = Marshal.SizeOf(typeof(BitmapFileHeader));
            var fileHeader      = BitmapFileHeader.Create(infoHeader);
            var fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);

            using (var bitmapStream = new MemoryStream())
            {
                bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
                bitmapStream.Write(format17Bytes, 0, format17Bytes.Length);
                bitmapStream.Seek(0, SeekOrigin.Begin);
                var image = BitmapHelper.FromStream(bitmapStream);
                if (image != null)
                {
                    return(image);
                }
            }
            return(null);
        }
Example #12
0
        /// <summary>Reads header information from a stream.</summary>
        private void Initialise(Stream stream)
        {
            BinaryReader rdr;
            int          first;

            try
            {
                rdr   = new BinaryReader(stream);
                first = rdr.PeekChar();
            }
            catch (ArgumentException aex) { throw new DibException("Unable to initialise DIB", aex); }

            // see if it has a BitmapFileHeader at the beginning
            if (first == 'B')
            {
                _fileHeader = new BitmapFileHeader(rdr);
            }

            // determine the Dib type (the BitmapFileHeader will have advanced the reader)
            // maybe do some validation on the structs?

            switch (rdr.PeekChar())
            {
            case 12:
                Class = DibClass.Core;
                break;

            case 40:
                Class = DibClass.V3;
                break;

            case 108:
                Class = DibClass.V4;
                break;

            case 124:
                Class = DibClass.V5;
                break;

            default:
                throw new DibException("Unrecognised BitmapInfoHeader dwSize");
            }

            _infoHeader = FillBitmapHeader(rdr, Class);

            if (_fileHeader.bfType == 0)
            {
                // if no fileheader was read earlier
                // create the FileHeader

                _fileHeader = CreateFileHeader();
            }
            else
            {
                // resize the data array to remove the fileheader

                var sizeOfBitmapFileHeader = Marshal.SizeOf(typeof(BitmapFileHeader));

                var newData = new byte[_dibData.Length - sizeOfBitmapFileHeader];

                Array.Copy(_dibData, sizeOfBitmapFileHeader, newData, 0, newData.Length);

                _dibData = newData;
            }
        }
Example #13
0
        /// <summary>
        /// bitmapのロード
        /// </summary>
        /// <param name="path"></param>
        /// <param name="bfh"></param>
        /// <param name="bih"></param>
        /// <param name="colorPal"></param>
        /// <param name="bitData"></param>
        /// <returns></returns>
        private static bool Load(string path, out BitmapFileHeader bfh, out BitmapInfoHeader bih, out Color[] colorPal, out byte[] bitData)
        {
            var ext = Path.GetExtension(path).ToLower();

            if (ext != ".bmp")
            {
                goto ErrorHandler;
            }

            var        readData = new byte[4];
            FileStream fs;

            try
            {
                fs = File.Open(path, FileMode.Open, FileAccess.Read);
                if (fs == null)
                {
                    goto ErrorHandler;
                }
            }
            catch
            {
                goto ErrorHandler;
            }

            // ヘッダ情報読み込み
            fs.Read(readData, 0, 2);
            bfh.fType = BitConverter.ToUInt16(readData, 0);
            fs.Read(readData, 0, 4);
            bfh.fSize = BitConverter.ToUInt32(readData, 0);
            fs.Read(readData, 0, 2);
            bfh.fReserved1 = BitConverter.ToUInt16(readData, 0);
            fs.Read(readData, 0, 2);
            bfh.fReserved2 = BitConverter.ToUInt16(readData, 0);
            fs.Read(readData, 0, 4);
            bfh.fOffset = BitConverter.ToUInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biSize = BitConverter.ToUInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biWidth = BitConverter.ToInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biHeight = BitConverter.ToInt32(readData, 0);
            fs.Read(readData, 0, 2);
            bih.biPlanes = BitConverter.ToUInt16(readData, 0);
            fs.Read(readData, 0, 2);
            bih.biBitCount = BitConverter.ToUInt16(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biCompression = BitConverter.ToUInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biSizeImage = BitConverter.ToUInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biXPelsPerMeter = BitConverter.ToInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biYPelsPerMeter = BitConverter.ToInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biClrUsed = BitConverter.ToUInt32(readData, 0);
            fs.Read(readData, 0, 4);
            bih.biClrImportant = BitConverter.ToUInt32(readData, 0);

            // データ読み込み
            long palSize = (bfh.fOffset - 14 - 40) / 4;

            if (palSize != 0)
            {
                colorPal = new Color[palSize];
                for (int i = 0; i < palSize; ++i)
                {
                    fs.Read(readData, 0, 4);
                    colorPal[i] = new Color(readData[2], readData[1], readData[0], readData[3]);
                }
            }
            else
            {
                colorPal = null;
            }

            int stride = ((bih.biWidth * bih.biBitCount + 31) / 32) * 4;

            bitData = new byte[stride * bih.biHeight];

            for (int i = 0; i < bih.biHeight; ++i)
            {
                fs.Read(bitData, i * stride, stride);
            }

            // rgbの順がbgrなので入れ替え
            for (int i = 0; i < stride * bih.biHeight / 4; ++i)
            {
                var idx = i * 4;
                var t   = bitData[idx];
                bitData[idx]     = bitData[idx + 2];
                bitData[idx + 2] = t;
            }

            fs.Close();
            fs.Dispose();

            return(true);

ErrorHandler:
            Debug.LogError("-----BitmapLoaderError-----");
            bfh.fType      = 0;
            bfh.fSize      = 0;
            bfh.fReserved1 = 0;
            bfh.fReserved2 = 0;
            bfh.fOffset    = 0;

            bih.biSize          = 0;
            bih.biWidth         = 0;
            bih.biHeight        = 0;
            bih.biPlanes        = 0;
            bih.biBitCount      = 0;
            bih.biCompression   = 0;
            bih.biSizeImage     = 0;
            bih.biXPelsPerMeter = 0;
            bih.biYPelsPerMeter = 0;
            bih.biClrUsed       = 0;
            bih.biClrImportant  = 0;

            colorPal = null;
            bitData  = null;
            return(false);
        }
Example #14
0
        /// <summary>
        ///     Helper method to try to get an image in the specified format from the dataObject
        ///     the DIB reader should solve some issues
        ///     It also supports Format17/DibV5, by using the following information: http://stackoverflow.com/a/14335591
        /// </summary>
        /// <param name="format">string with the format</param>
        /// <param name="dataObject">IDataObject</param>
        /// <returns>Bitmap or null</returns>
        private static Bitmap GetBitmapForFormat(string format, IDataObject dataObject)
        {
            var clipboardObject = GetFromDataObject(dataObject, format);
            var imageStream     = clipboardObject as MemoryStream;

            if (!IsValidStream(imageStream))
            {
                // TODO: add "HTML Format" support here...
                return(clipboardObject as Bitmap);
            }
            if (CoreConfig.EnableSpecialDIBClipboardReader)
            {
                if (format == FORMAT_17 || format == DataFormats.Dib)
                {
                    Log.Info().WriteLine("Found DIB stream, trying to process it.");
                    try
                    {
                        if (imageStream != null)
                        {
                            var dibBuffer = new byte[imageStream.Length];
                            imageStream.Read(dibBuffer, 0, dibBuffer.Length);
                            var infoHeader = BinaryStructHelper.FromByteArray <BitmapInfoHeader>(dibBuffer);
                            if (!infoHeader.IsDibV5)
                            {
                                Log.Info().WriteLine("Using special DIB <v5 format reader with biCompression {0}", infoHeader.Compression);
                                var fileHeaderSize  = Marshal.SizeOf(typeof(BitmapFileHeader));
                                var fileHeader      = BitmapFileHeader.Create(infoHeader);
                                var fileHeaderBytes = BinaryStructHelper.ToByteArray(fileHeader);

                                using (var bitmapStream = new MemoryStream())
                                {
                                    bitmapStream.Write(fileHeaderBytes, 0, fileHeaderSize);
                                    bitmapStream.Write(dibBuffer, 0, dibBuffer.Length);
                                    bitmapStream.Seek(0, SeekOrigin.Begin);
                                    var image = BitmapHelper.FromStream(bitmapStream);
                                    if (image != null)
                                    {
                                        return(image);
                                    }
                                }
                            }
                            else
                            {
                                Log.Info().WriteLine("Using special DIBV5 / Format17 format reader");
                                // CF_DIBV5
                                var gcHandle = IntPtr.Zero;
                                try
                                {
                                    var handle = GCHandle.Alloc(dibBuffer, GCHandleType.Pinned);
                                    gcHandle = GCHandle.ToIntPtr(handle);
                                    return
                                        (new Bitmap(infoHeader.Width, infoHeader.Height,
                                                    -(int)(infoHeader.SizeImage / infoHeader.Height),
                                                    infoHeader.BitCount == 32 ? PixelFormat.Format32bppArgb : PixelFormat.Format24bppRgb,
                                                    new IntPtr(handle.AddrOfPinnedObject().ToInt32() + infoHeader.OffsetToPixels + (infoHeader.Height - 1) * (int)(infoHeader.SizeImage / infoHeader.Height))
                                                    ));
                                }
                                catch (Exception ex)
                                {
                                    Log.Error().WriteLine(ex, "Problem retrieving Format17 from clipboard.");
                                }
                                finally
                                {
                                    if (gcHandle == IntPtr.Zero)
                                    {
                                        GCHandle.FromIntPtr(gcHandle).Free();
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception dibEx)
                    {
                        Log.Error().WriteLine(dibEx, "Problem retrieving DIB from clipboard.");
                    }
                }
            }
            else
            {
                Log.Info().WriteLine("Skipping special DIB format reader as it's disabled in the configuration.");
            }
            try
            {
                if (imageStream != null)
                {
                    imageStream.Seek(0, SeekOrigin.Begin);
                    var tmpImage = BitmapHelper.FromStream(imageStream);
                    if (tmpImage != null)
                    {
                        Log.Info().WriteLine("Got image with clipboard format {0} from the clipboard.", format);
                        return(tmpImage);
                    }
                }
            }
            catch (Exception streamImageEx)
            {
                Log.Error().WriteLine(streamImageEx, $"Problem retrieving {format} from clipboard.");
            }
            return(null);
        }
Example #15
0
        /// <summary>
        /// Convert a DeviceIndependentBitmap to a <see cref="BitmapSource"/>
        /// </summary>
        /// <param name="memoryStream">The <see cref="MemoryStream"/> to convert</param>
        /// <param name="maxHeight">The maximum height of the picture. Use null to don't specify a maximum height</param>
        /// <returns>Returns a <see cref="BitmapSource"/>. If the memoryStream is null, returns null.</returns>
        internal static BitmapSource DeviceIndependentBitmapToBitmapSource(MemoryStream memoryStream, int?maxHeight)
        {
            if (memoryStream == null)
            {
                return(null);
            }

            var bytes = memoryStream.ToArray();
            var resultMemoryStream = new MemoryStream();
            var width  = BitConverter.ToInt32(bytes, 4);
            var height = BitConverter.ToInt32(bytes, 8);
            var bpp    = BitConverter.ToInt16(bytes, 14);

            if (bpp == 32)
            {
                // Potentially, this way of convert, by using System.Drawing.Bitmap (non-WPF) can keep the transparency of the picture.
                var    gch = GCHandle.Alloc(bytes, GCHandleType.Pinned);
                Bitmap bmp = null;
                try
                {
                    var ptr = new IntPtr((long)gch.AddrOfPinnedObject() + 40);
                    bmp = new Bitmap(width, height, width * 4, PixelFormat.Format32bppRgb, ptr);
                    bmp.MakeTransparent(Color.Transparent);
                    bmp.RotateFlip(RotateFlipType.Rotate180FlipX);

                    bmp.Save(resultMemoryStream, ImageFormat.Png);
                }
                finally
                {
                    gch.Free();
                    if (bmp != null)
                    {
                        bmp.Dispose();
                    }
                }
            }
            else
            {
                // This way does not keep transparency
                var infoHeader = FromByteArrayToStruct <BitmapInfoHeader>(bytes);

                var fileHeaderSize = Marshal.SizeOf(typeof(BitmapFileHeader));
                var infoHeaderSize = infoHeader.biSize;
                var fileSize       = fileHeaderSize + infoHeader.biSize + infoHeader.biSizeImage;

                var fileHeader = new BitmapFileHeader
                {
                    bfType      = BitmapFileHeader.BM,
                    bfSize      = fileSize,
                    bfReserved1 = 0,
                    bfReserved2 = 0,
                    bfOffBits   = fileHeaderSize + infoHeaderSize + infoHeader.biClrUsed * 4
                };

                var fileHeaderBytes = StructToByteArray(fileHeader);

                resultMemoryStream.Write(fileHeaderBytes, 0, fileHeaderSize);
                resultMemoryStream.Write(bytes, 0, bytes.Length);
                resultMemoryStream.Seek(0, SeekOrigin.Begin);

                resultMemoryStream.Flush();
            }

            var result = new BitmapImage();

            result.BeginInit();
            result.CacheOption   = BitmapCacheOption.OnLoad;
            result.CreateOptions = BitmapCreateOptions.PreservePixelFormat;

            if (maxHeight.HasValue)
            {
                result.DecodePixelHeight = maxHeight.Value;
            }

            result.StreamSource = resultMemoryStream;
            result.EndInit();
            result.Freeze();

            return(result);
        }
Example #16
0
    public void Other()
    {
        var hDc    = User32.GetWindowDC(IntPtr.Zero);
        var hMemDc = Gdi32.CreateCompatibleDC(hDc);

        var bi = new BitmapInfoHeader();

        bi.biSize         = (uint)Marshal.SizeOf(bi);
        bi.biBitCount     = 24; //Creating RGB bitmap. The following three members don't matter
        bi.biClrUsed      = 0;
        bi.biClrImportant = 0;
        bi.biCompression  = 0;
        bi.biHeight       = Height;
        bi.biWidth        = Width;
        bi.biPlanes       = 1;

        var cb = (int)(bi.biHeight * bi.biWidth * bi.biBitCount / 8); //8 is bits per byte.

        bi.biSizeImage = (uint)(((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight);
        //bi.biXPelsPerMeter = XPelsPerMeter;
        //bi.biYPelsPerMeter = YPelsPerMeter;
        bi.biXPelsPerMeter = 96;
        bi.biYPelsPerMeter = 96;

        var pBits = IntPtr.Zero;
        //Allocate memory for bitmap bits
        var pBI = Kernel32.LocalAlloc((uint)LocalMemoryFlags.LPTR, new UIntPtr(bi.biSize));

        // Not sure if this needed - simply trying to keep marshaller happy
        Marshal.StructureToPtr(bi, pBI, false);
        //This will return IntPtr to actual DIB bits in pBits
        var hBmp = Gdi32.CreateDIBSection(hDc, ref pBI, 0, out pBits, IntPtr.Zero, 0);
        //Marshall back - now we have BitmapInfoHeader correctly filled in Marshal.PtrToStructure(pBI, bi);

        var biNew = (BitmapInfoHeader)Marshal.PtrToStructure(pBI, typeof(BitmapInfoHeader));
        //Usual stuff
        var hOldBitmap = Gdi32.SelectObject(hMemDc, hBmp);
        //Grab bitmap
        var nRet = Gdi32.BitBlt(hMemDc, 0, 0, bi.biWidth, bi.biHeight, hDc, Left, Top, CopyPixelOperations.SourceCopy | CopyPixelOperations.CaptureBlt);

        // Allocate memory for a copy of bitmap bits
        var realBits = new byte[cb];

        // And grab bits from DIBSestion data
        Marshal.Copy(pBits, realBits, 0, cb);

        //This simply creates valid bitmap file header, so it can be saved to disk
        var bfh = new BitmapFileHeader();

        bfh.bfSize    = (uint)cb + 0x36; // Size of header + size of Native.BitmapInfoHeader size of bitmap bits
        bfh.bfType    = 0x4d42;          //BM
        bfh.bfOffBits = 0x36;            //
        var hdrSize = 14;
        var header  = new byte[hdrSize];

        BitConverter.GetBytes(bfh.bfType).CopyTo(header, 0);
        BitConverter.GetBytes(bfh.bfSize).CopyTo(header, 2);
        BitConverter.GetBytes(bfh.bfOffBits).CopyTo(header, 10);
        //Allocate enough memory for complete bitmap file
        var data = new byte[cb + bfh.bfOffBits];

        //BITMAPFILEHEADER
        header.CopyTo(data, 0);

        //BitmapInfoHeader
        header = new byte[Marshal.SizeOf(bi)];
        var pHeader = Kernel32.LocalAlloc((uint)LocalMemoryFlags.LPTR, new UIntPtr((uint)Marshal.SizeOf(bi)));

        Marshal.StructureToPtr(biNew, pHeader, false);
        Marshal.Copy(pHeader, header, 0, Marshal.SizeOf(bi));
        Kernel32.LocalFree(pHeader);
        header.CopyTo(data, hdrSize);
        //Bitmap bits
        realBits.CopyTo(data, (int)bfh.bfOffBits);

        //Native.SelectObject(_compatibleDeviceContext, _oldBitmap);
        //Native.DeleteObject(_compatibleBitmap);
        //Native.DeleteDC(_compatibleDeviceContext);
        //Native.ReleaseDC(_desktopWindow, _windowDeviceContext);

        Gdi32.SelectObject(hMemDc, hOldBitmap);
        Gdi32.DeleteObject(hBmp);
        Gdi32.DeleteDC(hMemDc);
        User32.ReleaseDC(IntPtr.Zero, hDc);
    }
Example #17
0
        /// <summary>
        /// Read the DIB of the indicated frame and report it as a
        /// raw <see cref="Image"/>.
        /// </summary>
        /// <param name="frameNumber">The zero based frame index.</param>
        /// <param name="imageStream">Must be closed by the caller when the
        /// returned <see cref="Image"/> is no longer needed.</param>
        /// <returns>The frame pixels or <i>null</i> if the indicated
        /// frame does not exist.</returns>
        public Image GetFrame( int frameNumber, out Stream imageStream )
        {
            // Clear output
            imageStream = null;

            // Try to read DIB
            IntPtr rDIB = AVIStreamGetFrame( m_Frame, frameNumber );

            // None
            if (IntPtr.Zero == rDIB)
                return null;

            // Read the sizes
            int fSize = BitmapFileHeader.SizeOf;
            short hSize = Marshal.ReadInt16( rDIB, 0 );
            int iSize = Marshal.ReadInt32( rDIB, 20 );

            // Create proper file header header
            BitmapFileHeader pHead = new BitmapFileHeader();
            pHead.bfType = 0x4D42;
            pHead.bfReserved1 = 0;
            pHead.bfReserved2 = 0;
            pHead.bfOffBits = fSize + hSize;
            pHead.bfSize = pHead.bfOffBits + iSize;

            // Allocate buffer
            byte[] aBuf = new byte[pHead.bfSize];

            // For a moment use unmanaged memory
            GCHandle hHead = GCHandle.Alloc( pHead, GCHandleType.Pinned );

            // With cleanup
            try
            {
                // Copy header in
                Marshal.Copy( hHead.AddrOfPinnedObject(), aBuf, 0, fSize );
            }
            finally
            {
                // Relax
                hHead.Free();
            }

            // Copy DIB in
            Marshal.Copy( rDIB, aBuf, fSize, hSize + iSize );

            // Create output stream
            MemoryStream pOut = new MemoryStream( aBuf, false );

            // With cleanup
            try
            {
                // Load an image
                Image pRet = Image.FromStream( pOut );

                // Report result
                imageStream = pOut;

                // Do not clear
                pOut = null;

                // Report
                return pRet;
            }
            finally
            {
                // Stream no longer used
                if (null != pOut) pOut.Close();
            }
        }