Beispiel #1
0
        private FreeImageBitmap CreateFreeImageViaDIB()
        {
            FreeImageBitmap fi;

            using (DllManager dllManager = new DllManager())
            {
                dllManager.LoadDll("FreeImage.DLL");
                Logger.Info("CreateFreeImageViaDIB: Copy to clipboard and get data from it");
                if (!CopySelection())
                {
                    return(null);
                }

                MemoryStream stream = Clipboard.GetData(System.Windows.DataFormats.Dib) as MemoryStream;
                using (DibBitmap dibBitmap = new DibBitmap(stream))
                {
                    Logger.Info("CreateFreeImageViaDIB: Create FreeImage bitmap");
                    fi = new FreeImageBitmap(dibBitmap.Bitmap);
                    bool convertType = fi.ConvertType(FREE_IMAGE_TYPE.FIT_BITMAP, true);
                    Logger.Debug("CreateFreeImageViaDIB: FreeImageBitmap.ConvertType returned {0}", convertType);
                    bool convertColorDepth = fi.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); // won't work with 32 bpp!
                    Logger.Debug("CreateFreeImageViaDIB: FreeImageBitmap.ConvertColorDepth returned {0}", convertColorDepth);
                    fi.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY);
                }
            }
            return(fi);
        }
Beispiel #2
0
        private FreeImageBitmap CreateFreeImageViaDIB()
        {
            if (!CopySelection())
            {
                return(null);
            }
            FreeImageBitmap fi;
            MemoryStream    stream = null;

            Bovender.WpfHelpers.MainDispatcher.Invoke((Action)(
                                                          () =>
            {
                Logger.Info("CreateFreeImageViaDIB: Copy to clipboard and get data from it");
                stream = Clipboard.GetData(System.Windows.DataFormats.Dib) as MemoryStream;
            })
                                                      );
            using (DibBitmap dibBitmap = new DibBitmap(stream))
            {
                Logger.Info("CreateFreeImageViaDIB: Create FreeImage bitmap");
                fi = new FreeImageBitmap(dibBitmap.Bitmap);
                bool convertType = fi.ConvertType(FREE_IMAGE_TYPE.FIT_BITMAP, true);
                Logger.Debug("CreateFreeImageViaDIB: FreeImageBitmap.ConvertType returned {0}", convertType);
                bool convertColorDepth = fi.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP); // won't work with 32 bpp!
                Logger.Debug("CreateFreeImageViaDIB: FreeImageBitmap.ConvertColorDepth returned {0}", convertColorDepth);
                fi.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY);
            }
            stream.Dispose();
            return(fi);
        }
Beispiel #3
0
        public static FreeImageBitmap LoadImage(Stream ajpStream)
        {
            MemoryStream jpegFile;
            MemoryStream pmsFile;
            AjpHeader    ajpHeader;

            LoadImage(ajpStream, out jpegFile, out pmsFile, out ajpHeader);
            if (jpegFile == null)
            {
                return(null);
            }

            jpegFile.Position = 0;
            FreeImageBitmap jpegImage = new FreeImageBitmap(jpegFile, FREE_IMAGE_FORMAT.FIF_JPEG);

            jpegImage.Tag     = ajpHeader;
            jpegImage.Comment = ajpHeader.GetComment();

            if (pmsFile != null && pmsFile.Length > 0)
            {
                pmsFile.Position = 0;
                using (var pmsImage = Pms.LoadImage(pmsFile.ToArray()))
                {
                    if (pmsImage == null)
                    {
                        return(jpegImage);
                    }
                    jpegImage.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP);
                    jpegImage.SetChannel(pmsImage, FREE_IMAGE_COLOR_CHANNEL.FICC_ALPHA);
                }
            }

            return(jpegImage);
        }
Beispiel #4
0
        public void makeSampleImage(FreeImageBitmap bitmap)
        {
            if (LoadLogo != null)
            {
                using (FreeImageBitmap logo = LoadLogo())
                {
                    float sizeRatio       = (float)bitmap.Width / logo.Width;
                    int   finalLogoWidth  = (int)(logo.Width * sizeRatio);
                    int   finalLogoHeight = (int)(logo.Height * sizeRatio);
                    int   currentY        = 0;
                    int   imageHeight     = bitmap.Height;
                    bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP);

                    logo.Rescale(finalLogoWidth, finalLogoHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR);
                    while (currentY < imageHeight)
                    {
                        int sectionHeight = logo.Height;
                        if (currentY + sectionHeight > imageHeight)
                        {
                            sectionHeight = imageHeight - currentY;
                        }
                        using (FreeImageBitmap section = bitmap.Copy(0, currentY, logo.Width, currentY + sectionHeight))
                        {
                            using (FreeImageBitmap logoComposite = logo.Copy(0, 0, logo.Width, sectionHeight))
                            {
                                logoComposite.Composite(false, null, section);
                                bitmap.Paste(logoComposite, 0, currentY, int.MaxValue);
                                currentY += finalLogoHeight;
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
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);
        }
Beispiel #6
0
        public static void SaveImage(Stream stream, FreeImageBitmap bitmap)
        {
            string comment   = bitmap.Comment;
            var    vspHeader = new VspHeader();

            if (!String.IsNullOrEmpty(comment))
            {
                vspHeader.ParseComment(comment);
            }
            if (bitmap.ColorDepth != 4 && bitmap.ColorDepth != 8)
            {
                if (bitmap.ColorDepth > 8)
                {
                    if (bitmap.ColorDepth == 32)
                    {
                        bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP);
                    }
                    if (vspHeader.is8Bit == 0)
                    {
                        bitmap.Quantize(FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, 16);
                    }
                    else
                    {
                        bitmap.Quantize(FREE_IMAGE_QUANTIZE.FIQ_WUQUANT, 256);
                    }
                }
                //throw new ArgumentException("image must be 4-bit or 8-bit");
            }
            if ((bitmap.Width & 7) != 0)
            {
                int slackPixels = (bitmap.Width & 7);
                int pixelsToAdd = 8 - slackPixels;
                bitmap.EnlargeCanvas <RGBQUAD>(0, 0, pixelsToAdd, 0, new RGBQUAD(Color.Black));
            }

            if (vspHeader.is8Bit == 0)
            {
                vspHeader.height = bitmap.Height;
                vspHeader.width  = bitmap.Width / 8;
                SaveHeader(vspHeader, stream);
                SavePalette(bitmap.Palette, stream);
                SaveImageData(stream, bitmap);
            }
            else
            {
                vspHeader.height = bitmap.Height;
                if (vspHeader.width != bitmap.Width - 1)
                {
                }
                vspHeader.width = bitmap.Width - 1;
                SaveHeader(vspHeader, stream);
                var pmsHeader = vspHeader.ToPmsHeader();
                Pms.SavePalette(stream, bitmap.Palette);
                Pms.SaveImageData8Bit(stream, bitmap);
            }
        }
Beispiel #7
0
 private void ConvertColor(FreeImageBitmap freeImageBitmap)
 {
     if (Preset.UseColorProfile)
     {
         Logger.Info("ConvertColor: Convert color using profile");
         ViewModels.ColorProfileViewModel targetProfile =
             ViewModels.ColorProfileViewModel.CreateFromName(Preset.ColorProfile);
         targetProfile.TransformFromStandardProfile(freeImageBitmap);
         freeImageBitmap.ConvertColorDepth(Preset.ColorSpace.ToFreeImageColorDepth());
     }
     else
     {
         Logger.Info("ConvertColor: Convert color without profile");
         freeImageBitmap.ConvertColorDepth(Preset.ColorSpace.ToFreeImageColorDepth());
     }
     if (Preset.ColorSpace == ColorSpace.Monochrome)
     {
         SetMonochromePalette(freeImageBitmap);
     }
 }
Beispiel #8
0
        public void writeText(FreeImageBitmap bitmap, string p, int fontSize)
        {
            p = p.Replace("\n", "<br/>");

            int width  = Math.Min(bitmap.Width, 2048);
            int height = Math.Min(bitmap.Height, 256);

            ImageBox     imageBox     = (ImageBox)Gui.Instance.createWidgetT("ImageBox", "ImageBox", 0, 0, width, height, Align.Default, "Overlapped", "TempImageBox");
            RocketWidget rocketWidget = null;

            try
            {
                imageBox.Visible = false;
                rocketWidget     = new RocketWidget(imageBox, true);

                var cornerColor = Engine.Color.FromARGB(bitmap.GetPixel(0, 0).ToArgb());
                rocketWidget.resized();
                StringBuilder sb = new StringBuilder();
                sb.AppendFormat(DocumentStart, cornerColor.ToHexString(), fontSize);
                sb.AppendFormat("<p>{0}</p>", p);
                sb.Append(DocumentEnd);

                var resourceLoader = new RocketAssemblyResourceLoader(this.GetType().Assembly);
                RocketInterface.Instance.FileInterface.addExtension(resourceLoader);

                var document = rocketWidget.Context.LoadDocumentFromMemory(sb.ToString());
                if (document != null)
                {
                    document.Show(ElementDocument.FocusFlags.NONE);
                }

                RocketInterface.Instance.FileInterface.removeExtension(resourceLoader);

                using (FreeImageBitmap copyrightBitmap = new FreeImageBitmap(imageBox.Width, imageBox.Height, PixelFormat.Format32bppArgb))
                {
                    rocketWidget.writeToGraphics(copyrightBitmap, new Rectangle(0, 0, copyrightBitmap.Width, copyrightBitmap.Height));
                    using (FreeImageBitmap background = bitmap.Copy(0, 0, Math.Min(copyrightBitmap.Width, bitmap.Width), Math.Min(copyrightBitmap.Height, bitmap.Height)))
                    {
                        background.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP);
                        copyrightBitmap.Composite(false, null, background);
                        bitmap.Paste(copyrightBitmap, 0, 0, int.MaxValue);
                    }
                }
            }
            finally
            {
                //Using block does not work (wtf?), dispose manually
                if (rocketWidget != null)
                {
                    rocketWidget.Dispose();
                }
                Gui.Instance.destroyWidget(imageBox);
            }
        }
Beispiel #9
0
        public static unsafe void RemapPalette(FreeImageBitmap bitmap, FreeImageBitmap referenceImage, int numberOfColors)
        {
            using (FreeImageBitmap bitmap32 = bitmap.GetColorConvertedInstance(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP))
            {
                if (referenceImage.Height < bitmap.Height || referenceImage.Width < bitmap.Width)
                {
                    int h2 = referenceImage.Height;
                    if (h2 < bitmap.Height)
                    {
                        h2 = bitmap.Height;
                    }
                    int w2 = referenceImage.Width;
                    if (w2 < bitmap.Width)
                    {
                        w2 = bitmap.Width;
                    }
                    referenceImage.EnlargeCanvas <byte>(0, 0, w2 - referenceImage.Width, h2 - referenceImage.Height, 0);
                }

                //FreeImageBitmap reference32 = bitmap.GetColorConvertedInstance(FREE_IMAGE_COLOR_DEPTH.FICD_32_BPP);

                if (bitmap.ColorDepth != 8)
                {
                    bitmap.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP);
                }
                int *newPalette = (int *)(referenceImage.Palette.BaseAddress);

                int h = bitmap.Height;
                int w = bitmap.Width;

                //Ties are broken in ColorToIndex by popularity in the original image
                Dictionary <int, int> ColorToIndex = new Dictionary <int, int>();
                int[] ColorHistogram = new int[256];
                for (int y = 0; y < h; y++)
                {
                    byte *srcScanline = (byte *)(referenceImage.GetScanlineFromTop8Bit(y).BaseAddress);
                    for (int x = 0; x < w; x++)
                    {
                        int c = srcScanline[x];
                        ColorHistogram[c]++;
                    }
                }

                //add each palette color to the dictionary
                for (int i = 0; i < numberOfColors; i++)
                {
                    int c = newPalette[i] & 0xFFFFFF;
                    if (ColorToIndex.ContainsKey(c))
                    {
                        int otherIndex = ColorToIndex[c];
                        if (ColorHistogram[i] > ColorHistogram[otherIndex])
                        {
                            ColorToIndex[c] = i;
                        }
                    }
                    else
                    {
                        ColorToIndex[c] = i;
                    }
                }

                for (int y = 0; y < h; y++)
                {
                    int * trueColorScanline = (int *)(bitmap32.GetScanlineFromTop32Bit(y).BaseAddress);
                    byte *srcScanline       = (byte *)(bitmap.GetScanlineFromTop8Bit(y).BaseAddress);
                    byte *referenceScanline = (byte *)(referenceImage.GetScanlineFromTop8Bit(y).BaseAddress);

                    for (int x = 0; x < w; x++)
                    {
                        int srcColor = trueColorScanline[x] & 0xFFFFFF;
                        int refIndex = referenceScanline[x];
                        int refColor = newPalette[refIndex] & 0xFFFFFF;
                        if (srcColor == refColor)
                        {
                            srcScanline[x] = (byte)refIndex;
                        }
                        else
                        {
                            if (ColorToIndex.ContainsKey(srcColor))
                            {
                                int newColorIndex = ColorToIndex[srcColor];
                                if (refColor == (newPalette[newColorIndex] & 0xFFFFFF))
                                {
                                    srcScanline[x] = (byte)refIndex;
                                }
                                else
                                {
                                    srcScanline[x] = (byte)newColorIndex;
                                }
                            }
                            else
                            {
                                float minDistance = float.MaxValue;
                                int   minIndex    = 0;
                                for (int i = 0; i < numberOfColors; i++)
                                {
                                    int   c        = newPalette[i] & 0xFFFFFF;
                                    float distance = GetDistanceF(srcColor, c);
                                    if (distance < minDistance)
                                    {
                                        minIndex    = i;
                                        minDistance = distance;
                                    }
                                    else if (distance == minDistance && ColorHistogram[i] > ColorHistogram[minIndex])
                                    {
                                        minIndex = i;
                                    }
                                }
                                if (refColor == (newPalette[minIndex] & 0xFFFFFF))
                                {
                                    srcScanline[x] = (byte)refIndex;
                                }
                                else
                                {
                                    srcScanline[x] = (byte)minIndex;
                                }
                                ColorToIndex.Add(srcColor, minIndex);
                            }
                        }
                    }
                }
                bitmap.Palette.AsArray = referenceImage.Palette.AsArray;
            }
        }
Beispiel #10
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);
                }
            }
        }
Beispiel #11
0
        /// <summary>
        /// Compile input images into WAD texture file.
        /// </summary>
        /// <param name="outputFilename">Output wad file path.</param>
        /// <param name="images">Input image files.</param>
        /// <param name="names">Names of textures.</param>
        /// <param name="reserverLastPalColor">Reserve last color in palette if name starts with {.</param>
        public static void CreateWad(string outputFilename, string[] images, string[] names, Color alphaReplacementColor, bool reserverLastPalColor = false)
        {
            using (FileStream fs = new FileStream(outputFilename, FileMode.Create))
                using (BinaryWriter bw = new BinaryWriter(fs))
                {
                    //Convert bitmaps to 8bpp format
                    List <FreeImageBitmap> imgs = new List <FreeImageBitmap>();
                    for (int i = 0; i < images.Length; i++)
                    {
                        //Quantize images
                        FreeImageBitmap originalImage = new FreeImageBitmap(images[i]);

                        //If texture will be transparent, reserve last color if enabled
                        bool reserveLastClr     = (names[i].StartsWith("{") && reserverLastPalColor);
                        bool isTransparentImage = originalImage.IsTransparent;
                        bool is8Bpp             = originalImage.BitsPerPixel == 8;
                        int  r = reserveLastClr ? 1 : 0;

                        if (isTransparentImage)
                        {
                            originalImage.SwapColors(new RGBQUAD(Color.Transparent), new RGBQUAD(alphaReplacementColor), false);
                        }

                        originalImage.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors - r);
                        originalImage.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP);

                        if (reserveLastClr)
                        {
                            if (isTransparentImage)
                            {
                                bool foundReplacementColor = false;
                                for (int pindex = 0; pindex < originalImage.Palette.Length; pindex++)
                                {
                                    RGBQUAD rgb = originalImage.Palette.GetValue(pindex);
                                    if (rgb.rgbRed == alphaReplacementColor.R && rgb.rgbGreen == alphaReplacementColor.G && rgb.rgbBlue == alphaReplacementColor.B)
                                    {
                                        var lastColor = originalImage.Palette.GetValue(MaxPaletteColors - 1);
                                        originalImage.Palette[pindex] = lastColor;
                                        originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor);
                                        originalImage.SwapPaletteIndices((byte)pindex, MaxPaletteColors - 1);
                                        foundReplacementColor = true;
                                        break;
                                    }
                                }

                                // If didn't found replacement, set directly last alpha color
                                if (!foundReplacementColor)
                                {
                                    originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor);
                                }
                            }
                            else
                            {
                                originalImage.Palette[MaxPaletteColors - 1] = new RGBQUAD(alphaReplacementColor);
                            }
                        }

                        imgs.Add(originalImage);
                    }
                    uint[] offsets = new uint[images.Length];
                    uint[] sizes   = new uint[images.Length];

                    //WAD header
                    bw.Write(WadHeaderId);
                    bw.Write(images.Length);
                    bw.Write(0); //This will be changed later

                    //Write textures
                    for (int i = 0; i < images.Length; i++)
                    {
                        uint posTextureStart = (uint)bw.BaseStream.Position;
                        offsets[i] = posTextureStart;
                        //Texture name
                        byte[] name = CreateTextureName(names[i]);
                        bw.Write(name, 0, name.Length);

                        //Texture dimensions
                        bw.Write(imgs[i].Width);
                        bw.Write(imgs[i].Height);

                        //Offsets
                        uint posImage = (uint)(bw.BaseStream.Position - posTextureStart);
                        bw.Write(posImage + 16); //image
                        int pixelSize = ((imgs[i].Width) * (imgs[i].Height));
                        int m1        = ((imgs[i].Width / 2) * (imgs[i].Height / 2));
                        int m2        = ((imgs[i].Width / 4) * (imgs[i].Height / 4));
                        int m3        = ((imgs[i].Width / 8) * (imgs[i].Height / 8));
                        bw.Write((uint)(posImage + pixelSize + 16));           //mipmap1
                        bw.Write((uint)(posImage + pixelSize + m1 + 16));      //mipmap2
                        bw.Write((uint)(posImage + pixelSize + m1 + m2 + 16)); //mipmap3

                        //Write pixel data
                        imgs[i].RotateFlip(RotateFlipType.RotateNoneFlipX);
                        byte[] arr = new byte[imgs[i].Width * imgs[i].Height];
                        System.Runtime.InteropServices.Marshal.Copy(imgs[i].GetScanlinePointer(0), arr, 0, arr.Length);
                        Array.Reverse(arr);
                        bw.Write(arr);
                        //

                        //Mip map data
                        int factor = 2;
                        for (int a = 0; a < 3; a++)
                        {
                            int widthMM  = (imgs[i].Width / factor);
                            int heightMM = (imgs[i].Height / factor);

                            using (FreeImageBitmap clBmp = new FreeImageBitmap(imgs[i]))
                            {
                                //TODO: Transparent png
                                clBmp.Rescale(widthMM, heightMM, FREE_IMAGE_FILTER.FILTER_LANCZOS3);
                                clBmp.Quantize(FREE_IMAGE_QUANTIZE.FIQ_NNQUANT, MaxPaletteColors, imgs[i].Palette);

                                byte[] arrMM = new byte[widthMM * heightMM];
                                System.Runtime.InteropServices.Marshal.Copy(clBmp.GetScanlinePointer(0), arrMM, 0, arrMM.Length);
                                Array.Reverse(arrMM);
                                bw.Write(arrMM);
                            }
                            factor *= 2;
                        }

                        //Unknown 2 bytes
                        bw.Write(new byte[] { 0x00, 0x01 });

                        //Write color palette
                        for (int p = 0; p < imgs[i].Palette.Length; p++)
                        {
                            bw.Write(imgs[i].Palette[p].rgbRed);
                            bw.Write(imgs[i].Palette[p].rgbGreen);
                            bw.Write(imgs[i].Palette[p].rgbBlue);
                        }

                        //Padding
                        bw.Write(new byte[] { 0x00, 0x00 });
                        sizes[i] = (uint)bw.BaseStream.Position - posTextureStart;
                    }

                    long posLumps = bw.BaseStream.Position;
                    bw.Seek(8, SeekOrigin.Begin);
                    bw.Write((uint)posLumps);
                    bw.Seek((int)posLumps, SeekOrigin.Begin);
                    //Write Lumps infos
                    for (int i = 0; i < images.Length; i++)
                    {
                        bw.Write(offsets[i]);
                        bw.Write(sizes[i]);
                        bw.Write(sizes[i]);
                        bw.Write((byte)0x43);
                        bw.Write((byte)0);
                        bw.Write(new byte[] { 0x00, 0x00 });
                        byte[] name = CreateTextureName(names[i]);
                        bw.Write(name, 0, name.Length);
                    }

                    //Free resources
                    for (int i = 0; i < imgs.Count; i++)
                    {
                        imgs[i].Dispose();
                    }
                }
        }
Beispiel #12
0
        private IEnumerable <IdleStatus> createRender(int finalWidth, int finalHeight, int aaMode, bool showWatermark, bool transparentBG, Engine.Color backColor, Camera cloneCamera, Vector3 position, Vector3 lookAt, float minNearDistance, float nearPlaneWorld, float nearFarLength, ImageRendererProperties properties, Action <FreeImageBitmap> renderingCompletedCallback)
        {
            FreeImageBitmap  bitmap       = null;
            OgreSceneManager sceneManager = controller.CurrentScene.getDefaultSubScene().getSimElementManager <OgreSceneManager>();

            if (sceneManager != null)
            {
                bool doGridRender;
                int  backBufferWidth;
                int  backBufferHeight;

                using (TexturePtr texture = createOgreTexture(finalWidth, finalHeight, aaMode, out doGridRender, out backBufferWidth, out backBufferHeight))
                {
                    if (texture != null)
                    {
                        using (HardwarePixelBufferSharedPtr pixelBuffer = texture.Value.getBuffer())
                        {
                            RenderTexture renderTexture = pixelBuffer.Value.getRenderTarget();
                            Camera        camera        = sceneManager.SceneManager.createCamera("__PictureCamera");
                            camera.setLodBias(cloneCamera.getLodBias());
                            camera.setUseRenderingDistance(cloneCamera.getUseRenderingDistance());
                            camera.setNearClipDistance(cloneCamera.getNearClipDistance());
                            camera.setFarClipDistance(cloneCamera.getFarClipDistance());
                            camera.setPolygonMode(cloneCamera.getPolygonMode());
                            camera.setRenderingDistance(cloneCamera.getRenderingDistance());
                            camera.setProjectionType(cloneCamera.getProjectionType());
                            camera.setFOVy(cloneCamera.getFOVy());

                            camera.setAutoAspectRatio(false);
                            camera.setAspectRatio((float)finalWidth / finalHeight);

                            SceneNode node = sceneManager.SceneManager.createSceneNode("__PictureCameraNode");
                            node.attachObject(camera);
                            node.setPosition(position);
                            sceneManager.SceneManager.getRootSceneNode().addChild(node);
                            camera.lookAt(lookAt);
                            Viewport viewport = renderTexture.addViewport(camera, 1, 0.0f, 0.0f, 1.0f, 1.0f);

                            if (properties.UseIncludePoint)
                            {
                                Matrix4x4 viewMatrix       = camera.getViewMatrix();
                                Matrix4x4 projectionMatrix = camera.getProjectionMatrix();
                                float     aspect           = camera.getAspectRatio();
                                float     fovy             = camera.getFOVy() * 0.5f;

                                float   distance  = SceneViewWindow.computeOffsetToIncludePoint(viewMatrix, projectionMatrix, properties.IncludePoint, aspect, fovy);
                                Vector3 direction = (position - lookAt).normalized();
                                node.setPosition(position - (direction * distance));
                                camera.lookAt(lookAt);
                            }

                            if (transparentBG)
                            {
                                backColor.a = 0.0f;
                            }

                            ViewportBackground bgViewport = null;
                            if (background != null)
                            {
                                bgViewport = new ViewportBackground("ImageRenderer", 0, background, renderTexture, false);
                                bgViewport.BackgroundColor = backColor;
                                bgViewport.Camera.setAutoAspectRatio(false);
                                bgViewport.Camera.setAspectRatio((float)finalWidth / finalHeight);
                            }
                            viewport.setBackgroundColor(backColor);
                            viewport.setOverlaysEnabled(false);
                            viewport.setClearEveryFrame(false);

                            if (properties.CustomizeCameraPosition != null)
                            {
                                properties.CustomizeCameraPosition(camera, viewport);
                            }

                            float near = CameraPositioner.computeNearClipDistance(camera.getDerivedPosition().length(), minNearDistance, nearPlaneWorld);
                            camera.setNearClipDistance(near);
                            camera.setFarClipDistance(near + nearFarLength);

                            if (doGridRender)
                            {
                                IEnumerable <IdleStatus> process = gridRender(finalWidth * aaMode, finalHeight * aaMode, backBufferWidth, backBufferHeight, aaMode, renderTexture, camera, bgViewport != null ? bgViewport.Camera : null, transparentBG, backColor,
                                                                              (product) =>
                                {
                                    bitmap = product;
                                });
                                foreach (IdleStatus idleStatus in process)
                                {
                                    yield return(idleStatus);
                                }
                            }
                            else
                            {
                                bitmap = simpleRender(backBufferWidth, backBufferHeight, aaMode, transparentBG, backColor, renderTexture);
                            }

                            if (showWatermark && LoadLogo != null)
                            {
                                using (FreeImageBitmap logo = LoadLogo())
                                {
                                    float imageFinalHeight = bitmap.Height * 0.0447f;
                                    float scale            = imageFinalHeight / logo.Height;
                                    float imageFinalWidth  = logo.Width * scale;
                                    if (imageFinalWidth > bitmap.Width)
                                    {
                                        imageFinalWidth  = bitmap.Width;
                                        scale            = imageFinalWidth / logo.Width;
                                        imageFinalHeight = logo.Height * scale;
                                    }

                                    logo.Rescale((int)imageFinalWidth, (int)imageFinalHeight, FREE_IMAGE_FILTER.FILTER_BILINEAR);
                                    //Have to composite the logo image first.
                                    using (FreeImageBitmap fullImageCorner = bitmap.Copy(0, bitmap.Height - (int)imageFinalHeight, (int)imageFinalWidth, bitmap.Height))
                                    {
                                        fullImageCorner.ConvertColorDepth(FREE_IMAGE_COLOR_DEPTH.FICD_24_BPP);
                                        logo.Composite(false, null, fullImageCorner);
                                    }
                                    bitmap.Paste(logo, 0, bitmap.Height - (int)imageFinalHeight, int.MaxValue);
                                }
                            }

                            renderTexture.destroyViewport(viewport);
                            if (bgViewport != null)
                            {
                                bgViewport.Dispose();
                            }
                            sceneManager.SceneManager.getRootSceneNode().removeChild(node);
                            sceneManager.SceneManager.destroySceneNode(node);
                            sceneManager.SceneManager.destroyCamera(camera);

                            TextureManager.getInstance().remove(texture);
                        }
                    }
                    else
                    {
                        //An error making the render texture. Log it and return the error image.
                        Log.Error("Could not render image. Returning placeholder image. Reason: Could not create valid render to texture target.");
                        bitmap = new FreeImageBitmap(finalWidth, finalHeight);
                        bitmap.FillBackground(new RGBQUAD()
                        {
                            rgbRed = 255
                        });
                    }
                }
            }
            renderingCompletedCallback(bitmap);
            yield break;
        }