Exemplo n.º 1
0
        static BitmapCompression ChooseBestCompressionMode(int width, int height, UInt32 bpp, BitmapColor colorMode)
        {
            Int32 stride = MbmFile.GetStride(width, (Byte)bpp);

            if (width * height <= MaximumSizeNoCompress)
            {
                // At this size we should not compress. Not worth at all
                return(BitmapCompression.None);
            }

            switch (colorMode)
            {
            case BitmapColor.ColorWithAlpha:
                return(BitmapCompression.ThirtyTwoABitsRLE);

            case BitmapColor.ColorWithAlphaPM:
                return(BitmapCompression.ThirtyTwoABitsRLE);

            case BitmapColor.Color:
                break;

            default:
                throw new MbmException(String.Format("Unsupported bitmap color type to save: {0}", colorMode.ToString()));
            }

            switch (bpp)
            {
            case 32:
                return(BitmapCompression.ThirtyTwoUBitsRLE);

            case 24:
                return(BitmapCompression.TwentyFourBitsRLE);

            case 16:
                return(BitmapCompression.SixteenBitsRLE);

            case 12:
                return(BitmapCompression.TwelveBitsRLE);

            case 8:
                return(BitmapCompression.ByteRLE);

            default:
                break;
            }

            throw new MbmException(String.Format("Unsupported bits per pixel to save: {0}", bpp));
        }
Exemplo n.º 2
0
        public string RandomColor(Bitmap b, string type, long quality)
        {
            List <IDisposable> toDispose = new List <IDisposable>
            {
                b
            };

            if (type.ToLower() == "jpg")
            {
                type = "jpeg";
            }

            var formats = typeof(ImageFormat).GetProperties().Where(x => x.Name.ToLower() == type.ToLower());
            var s       = formats.Any() ? (ImageFormat)formats.First().GetValue(ImageFormat.Bmp, null) : ImageFormat.Jpeg; //kinda hacky but beats hardcoding

            ImageCodecInfo codecBlack = EncoderOf(s) ?? ImageCodecInfo.GetImageEncoders().Where(x => x.FormatID == ImageFormat.Jpeg.Guid).First();

            EncoderParameters eParams = new EncoderParameters(1);

            eParams.Param[0] = new EncoderParameter(Encoder.Quality, quality);

            string e    = type.ToLower() == "jpeg" ? "jpg" : s.ToString().ToLower();
            var    path = $"temp_{new Random().Next()}.{e}";

            if (b.PixelFormat != PixelFormat.Format24bppRgb)
            {
                var clone = new Bitmap(b.Width, b.Height, PixelFormat.Format24bppRgb);
                using (Graphics g = Graphics.FromImage(clone))
                {
                    g.DrawImage(b, new Rectangle(0, 0, b.Width, b.Height));
                    b.Dispose();
                    b = clone;
                    toDispose.Add(clone);
                }
            }

            var bData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat);
            var amnt  = Math.Abs(bData.Stride) * bData.Height;
            var vals  = new byte[amnt];
            var p     = bData.Scan0;

            Marshal.Copy(p, vals, 0, amnt);

            Dictionary <BitmapColor, BitmapColor> mapping = new Dictionary <BitmapColor, BitmapColor>();

            for (int i = 0; i < vals.Length; i += 3)
            {
                if (i + 2 >= vals.Length)
                {
                    break;
                }

                byte rVal = vals[i];
                byte gVal = vals[i + 1];
                byte bVal = vals[i + 2];

                BitmapColor pixel = new BitmapColor(rVal, gVal, bVal);
                BitmapColor mappedClr;

                if (!mapping.ContainsKey(pixel))
                {
                    var newClr = new BitmapColor((byte)_random.Next(256), (byte)_random.Next(256), (byte)_random.Next(256));
                    mapping.Add(pixel, newClr);
                    mappedClr = newClr;
                }
                else
                {
                    mappedClr = mapping[pixel];
                }

                vals[i]     = mappedClr.R;
                vals[i + 1] = mappedClr.G;
                vals[i + 2] = mappedClr.B;
            }

            Marshal.Copy(vals, 0, p, amnt);

            b.UnlockBits(bData);
            b.Save(path, codecBlack, eParams);
            foreach (var i in toDispose)
            {
                i.Dispose();
            }

            return(path);
        }
Exemplo n.º 3
0
        public static void Save(Document input, Stream output, Surface scratchSurface, UInt32 bpp, BitmapColor colorMode)
        {
            // Flatten the image first
            input.Flatten(scratchSurface);

            // Build up SBM Header
            SBMHeader header = new SBMHeader();

            header.headerLength       = 40;
            header.sizeInPixel.Width  = input.Width;
            header.sizeInPixel.Height = input.Height;
            header.sizeInTwips.Width  = input.Width * 15;
            header.sizeInTwips.Height = input.Height * 15;
            header.colorMode          = colorMode;
            header.bitsPerPixel       = bpp;

            // Determine what compression to use
            BitmapCompression compressionToUse = ChooseBestCompressionMode(input.Width, input.Height, bpp, colorMode);

            header.compression = compressionToUse;

            Int32 stride = MbmFile.GetStride(input.Width, (Byte)bpp);

            byte[] rawBitmapData        = new byte[stride * input.Height];
            byte[] compressedBitmapData = null;

            MemoryStream bitmapStream = new MemoryStream(rawBitmapData, 0, rawBitmapData.Length);

            ReadRawBitmapData(scratchSurface, bitmapStream, (Byte)bpp);

            bitmapStream.Seek(0, SeekOrigin.Begin);

            switch (compressionToUse)
            {
            case BitmapCompression comp when(comp >= BitmapCompression.ByteRLE && comp <= BitmapCompression.ThirtyTwoABitsRLE):
                compressedBitmapData = new byte[stride * input.Height];

                MemoryStream compressedDestStream = new MemoryStream(compressedBitmapData, 0, compressedBitmapData.Length);
                compressedDestStream.Seek(0, SeekOrigin.Begin);
                Algorithm.RLECompressor.Compress(compressedDestStream, bitmapStream, stride * input.Height, compressionToUse);
                header.bitmapSize = (UInt32)(40 + compressedDestStream.Position);

                break;

            case BitmapCompression.None:
                header.bitmapSize = (UInt32)(40 + stride * input.Height);
                break;

            default:
                throw new MbmException(String.Format("Unsupported bitmap compression type {0}", compressionToUse.ToString()));
            }

            output.Seek(/*sizeof(MbmHeader)*/ 20, SeekOrigin.Begin);

            MbmBinaryWriter writer = new MbmBinaryWriter(output);

            // Try to write our header
            writer.WriteUInt32(header.bitmapSize);
            writer.WriteUInt32(header.headerLength);
            writer.WriteSize(header.sizeInPixel);
            writer.WriteSize(header.sizeInTwips);
            writer.WriteUInt32(header.bitsPerPixel);
            writer.WriteUInt32((UInt32)header.colorMode);
            writer.WriteUInt32(header.paletteSize);
            writer.WriteUInt32((UInt32)header.compression);

            // Write data
            switch (compressionToUse)
            {
            case BitmapCompression comp when(comp >= BitmapCompression.ByteRLE && comp <= BitmapCompression.ThirtyTwoABitsRLE):
                output.Write(compressedBitmapData, 0, (int)(header.bitmapSize - header.headerLength));

                break;

            case BitmapCompression.None:
                output.Write(rawBitmapData, 0, rawBitmapData.Length);
                break;

            default:
                break;
            }

            // Write trailer
            UInt32 trailerOffset = writer.Tell();

            writer.WriteUInt32(1);
            writer.WriteUInt32(20);

            // Seek back and write our header
            writer.Seek(0);
            writer.WriteUInt32(MbmHeader.directFileStoreUIDNum);
            writer.WriteUInt32(MbmHeader.multiBitmapUIDNum);
            writer.WriteUInt32(0);
            writer.WriteUInt32(0);      // Checksum
            writer.WriteUInt32(trailerOffset);
        }