示例#1
0
        public static FreeImageBitmap LoadImage(byte[] bytes)
        {
            var qntHeader = GetQntHeader(bytes);

            if (qntHeader == null || !qntHeader.Validate())
            {
                return(null);
            }

            var pixels = GetQntPixels(bytes, qntHeader);

            byte[] alphaPixels = null;
            if (qntHeader.alphaSize != 0)
            {
                alphaPixels = GetQntAlpha(bytes, qntHeader);
            }

            FreeImageBitmap image = new FreeImageBitmap(qntHeader.width, qntHeader.height, qntHeader.width * 3, 24,
                                                        FREE_IMAGE_TYPE.FIT_BITMAP, pixels);

            using (var blue = image.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_RED))
                using (var red = image.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_BLUE)) {
                    if (alphaPixels != null)
                    {
                        image.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP);
                    }
                    image.SetChannel(blue, FREE_IMAGE_COLOR_CHANNEL.FICC_BLUE);
                    image.SetChannel(red, FREE_IMAGE_COLOR_CHANNEL.FICC_RED);
                }


            FreeImageBitmap alpha = null;

            try
            {
                if (alphaPixels != null)
                {
                    alpha = new FreeImageBitmap(qntHeader.width, qntHeader.height, qntHeader.width, 8,
                                                FREE_IMAGE_TYPE.FIT_BITMAP, alphaPixels);
                }

                if (alpha != null)
                {
                    image.SetChannel(alpha, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA);
                }
            }
            finally
            {
                if (alpha != null)
                {
                    alpha.Dispose();
                }
            }
            image.Comment = qntHeader.GetComment();
            image.Tag     = qntHeader;
            return(image);
        }
示例#2
0
        public static void SaveImage(Stream stream, FreeImageBitmap bitmap)
        {
            AjpHeader ajpHeaderFromBitmap  = bitmap.Tag as AjpHeader;
            AjpHeader ajpHeaderFromComment = null;

            if (!string.IsNullOrEmpty(bitmap.Comment))
            {
                ajpHeaderFromComment = new AjpHeader();
                if (!ajpHeaderFromComment.ParseComment(bitmap.Comment))
                {
                    ajpHeaderFromComment = null;
                }
            }

            var ms  = new MemoryStream();
            var ms2 = new MemoryStream();

            bitmap.Save(ms, FREE_IMAGE_FORMAT.FIF_JPEG, FREE_IMAGE_SAVE_FLAGS.JPEG_PROGRESSIVE | FREE_IMAGE_SAVE_FLAGS.JPEG_QUALITYGOOD);
            using (var alpha = bitmap.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA))
            {
                if (alpha != null)
                {
                    alpha.Comment = "signature = 19792, version = 2, headerSize = 64, colorDepth = 8";
                    Pms.SaveImage(ms2, alpha);
                }
            }

            AjpHeader ajpHeader = ajpHeaderFromBitmap;

            if (ajpHeader == null)
            {
                ajpHeader = ajpHeaderFromComment;
            }
            SaveImage(stream, ms.ToArray(), ms2.ToArray(), ajpHeader);
        }
示例#3
0
        public static void SaveImage(Stream stream, FreeImageBitmap bitmap)
        {
            string comment     = bitmap.Comment;
            var    pmsHeader   = new PmsHeader();
            bool   readComment = false;

            if (!string.IsNullOrEmpty(comment))
            {
                if (pmsHeader.ParseComment(comment))
                {
                    readComment = true;
                }
            }

            if (pmsHeader.colorDepth == 0)
            {
                pmsHeader.colorDepth = 8;
            }

            bool is8Bit = !readComment || pmsHeader.colorDepth == 8;

            if (!readComment)
            {
                pmsHeader.version    = 1;
                pmsHeader.headerSize = 48;
            }
            if (pmsHeader.signature == 0)
            {
                pmsHeader.signature = 0x00004d50;
            }
            if (pmsHeader.version == 2 && pmsHeader.headerSize == 0)
            {
                pmsHeader.headerSize = 64;
            }
            if (pmsHeader.headerSize < 48)
            {
                pmsHeader.headerSize = 48;
            }
            if (pmsHeader.headerSize > 64)
            {
                pmsHeader.headerSize = 64;
            }
            pmsHeader.addressOfComment = 0;
            pmsHeader.height           = bitmap.Height;
            pmsHeader.width            = bitmap.Width;

            if (is8Bit)
            {
                if (bitmap.ColorDepth > 8)
                {
                    if (bitmap.ColorDepth == 32)
                    {
                        bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP);
                    }
                    bitmap.Quantize(FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, 256);
                    //throw new ArgumentException("image must be 8-bit");
                }

                pmsHeader.addressOfPalette = pmsHeader.headerSize;
                pmsHeader.addressOfData    = pmsHeader.addressOfPalette + 768;
                pmsHeader.colorDepth       = 8;

                SaveHeader(stream, pmsHeader);
                SavePalette(stream, bitmap.Palette);
                SaveImageData8Bit(stream, bitmap);
            }
            else
            {
                bool hasAlphaChannel      = false;
                var  existingAlphaChannel = bitmap.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA);
                if (existingAlphaChannel != null)
                {
                    bool allPixelsOpaque = AllPixelsOpaque(existingAlphaChannel);
                    hasAlphaChannel = !allPixelsOpaque;
                }
                if (bitmap.ColorDepth != 32)
                {
                    bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP);
                }

                bool usingAlphaChannel = pmsHeader.shadowDepth == 8 || (pmsHeader.shadowDepth == 0 && hasAlphaChannel);

                pmsHeader.addressOfPalette = 0;
                pmsHeader.addressOfData    = pmsHeader.headerSize;
                pmsHeader.colorDepth       = 16;

                ushort[] image16 = new ushort[pmsHeader.width * pmsHeader.height];
                byte[]   image8  = null;
                if (usingAlphaChannel)
                {
                    image8 = new byte[pmsHeader.width * pmsHeader.height];
                }
                int o = 0;
                for (int y = 0; y < pmsHeader.height; y++)
                {
                    var scanline = bitmap.GetScanlineFromTop32Bit(y);

                    if (image8 == null)
                    {
                        for (int x = 0; x < pmsHeader.width; x++)
                        {
                            unchecked
                            {
                                int p = scanline[x];
                                int b = (p >> 0) & 0xFF;
                                int g = (p >> 8) & 0xFF;
                                int r = (p >> 16) & 0xFF;
                                //int a = (p >> 24) & 0xFF;
                                b = (b * 0x1F1F + 0x8000) >> 16;
                                g = (g * 0x3F3F + 0x8000) >> 16;
                                r = (r * 0x1F1F + 0x8000) >> 16;
                                p = (b << 0) |
                                    (g << 5) |
                                    (r << 11);
                                image16[o] = (ushort)p;
                                o++;
                            }
                        }
                    }
                    else
                    {
                        for (int x = 0; x < pmsHeader.width; x++)
                        {
                            unchecked
                            {
                                int p = scanline[x];
                                int b = (p >> 0) & 0xFF;
                                int g = (p >> 8) & 0xFF;
                                int r = (p >> 16) & 0xFF;
                                int a = (p >> 24) & 0xFF;
                                b = (b * 0x1F1F + 0x8000) >> 16;
                                g = (g * 0x3F3F + 0x8000) >> 16;
                                r = (r * 0x1F1F + 0x8000) >> 16;
                                p = (b << 0) |
                                    (g << 5) |
                                    (r << 11);
                                image16[o] = (ushort)p;
                                image8[o]  = (byte)a;
                                o++;
                            }
                        }
                    }
                }
                MemoryStream ms = new MemoryStream();

                SaveImageData16Bit(ms, image16, pmsHeader.width, pmsHeader.height);
                int imageSize = (int)ms.Length;
                if (usingAlphaChannel)
                {
                    pmsHeader.addressOfPalette = imageSize + pmsHeader.addressOfData;
                }
                SaveHeader(stream, pmsHeader);
                ms.WriteTo(stream);
                ms.SetLength(0);
                if (usingAlphaChannel)
                {
                    SaveImageData8Bit(stream, image8, pmsHeader.width, pmsHeader.height);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Write to the given graphics, if the widget texture is not large enough it will be
        /// resized temporarily and then sized back. So be careful with large destrects.
        /// </summary>
        /// <param name="g"></param>
        /// <param name="destRect"></param>
        public void writeToGraphics(FreeImageBitmap g, Rectangle destRect)
        {
            bool      changedSize  = false;
            IntSize2  originalSize = new IntSize2(imageBox.Width, imageBox.Height);
            float     cropRatio    = (float)imageBox.Width / destRect.Width;
            Rectangle srcRect      = new Rectangle(0, 0, imageBox.Width, (int)(destRect.Height * cropRatio));

            //Make sure the source image is large enough, if not resize.
            if (originalSize.Width < srcRect.Width || originalSize.Height < srcRect.Height)
            {
                imageBox.setSize(srcRect.Width, srcRect.Height);
                changedSize = true;
                resized();
                renderTexture.update();
            }
            else if (renderOneFrame)
            {
                renderTexture.update();
            }

            using (FreeImageBitmap fullBitmap = new FreeImageBitmap(currentTextureWidth, currentTextureHeight, BitmapFormat))
            {
                fullBitmap.copyFromRenderTarget(renderTexture, ogreTextureFormat);
                //Remove alpha
                //BitmapDataExtensions.SetAlpha(bmpData, 255);

                if (srcRect.Height > fullBitmap.Height)
                {
                    srcRect.Height = fullBitmap.Height;
                }

                using (FreeImageBitmap cropped = fullBitmap.Copy(srcRect))
                {
                    if (cropped != null)
                    {
                        cropped.Rescale(destRect.Width, destRect.Height, FREE_IMAGE_FILTER.FILTER_BILINEAR);
                        if (ogreTextureFormat == OgrePlugin.PixelFormat.PF_X8R8G8B8)
                        {
                            //Use the api to set the alpha channel to 255, this makes sure we dont carry over the x8 channel from ogre
                            using (var alpha = cropped.GetChannel(FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA))
                            {
                                alpha.FillBackground(new RGBQUAD(new FreeImageAPI.Color()
                                {
                                    R = 255,
                                    G = 255,
                                    B = 255,
                                    A = 255
                                }));
                                cropped.SetChannel(alpha, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA);
                            }
                        }
                        g.Paste(cropped, destRect.X, destRect.Y, int.MaxValue);
                    }
                }
            }

            if (changedSize)
            {
                imageBox.setSize(originalSize.Width, originalSize.Height);
                resized();
                renderTexture.update();
            }
        }