示例#1
0
        public static byte[] WicResize(IWICComponentFactory factory, byte[] photoBytes, int width, int height, int quality)
        {
            IWICBitmapDecoder decoder = null;
            var inputStream           = factory.CreateStream();

            try {
                inputStream.InitializeFromMemory(photoBytes, (uint)photoBytes.Length);
                decoder = factory.CreateDecoderFromStream(inputStream, null,
                                                          WICDecodeOptions.WICDecodeMetadataCacheOnLoad);
                return(WicResize(factory, decoder.GetFrame(0), width, height, quality));
            } finally {
                Marshal.ReleaseComObject(decoder);
                Marshal.ReleaseComObject(inputStream);
            }
        }
示例#2
0
        public void DecodeResizeAndEncode(byte[] fileBytes, long lData, uint width, uint height, Stream writeTo)
        {
            //A list of COM objects to destroy
            List <object> com = new List <object>();

            try {
                //Create the factory
                IWICComponentFactory factory = (IWICComponentFactory) new WICImagingFactory();
                com.Add(factory);

                //Wrap the byte[] with a IWICStream instance
                var streamWrapper = factory.CreateStream();
                streamWrapper.InitializeFromMemory(fileBytes, (uint)lData);
                com.Add(streamWrapper);

                var decoder = factory.CreateDecoderFromStream(streamWrapper, null,
                                                              WICDecodeOptions.WICDecodeMetadataCacheOnLoad);
                com.Add(decoder);

                IWICBitmapFrameDecode frame = decoder.GetFrame(0);
                com.Add(frame);


                var scaler = factory.CreateBitmapScaler();
                scaler.Initialize(frame, width, height, WICBitmapInterpolationMode.WICBitmapInterpolationModeFant);
                com.Add(scaler);


                var outputStream = new MemoryIStream();


                EncodeToStream(factory, scaler, outputStream);

                outputStream.WriteTo(writeTo);
            } finally {
                //Manually cleanup all the com reference counts, aggressively
                while (com.Count > 0)
                {
                    Marshal.ReleaseComObject(com[com.Count - 1]); //In reverse order, so no item is ever deleted out from under another.
                    com.RemoveAt(com.Count - 1);
                }
            }
        }
示例#3
0
文件: Utils.cs 项目: eakova/resizer
        public static byte[] WicResize(IWICComponentFactory factory, byte[] photoBytes, int width, int height, int quality)
        {
            IWICBitmapDecoder decoder = null ;
            var inputStream = factory.CreateStream();
            try {

                inputStream.InitializeFromMemory(photoBytes, (uint)photoBytes.Length);
                decoder = factory.CreateDecoderFromStream(inputStream, null,
                                                              WICDecodeOptions.WICDecodeMetadataCacheOnLoad);
                return WicResize(factory, decoder.GetFrame(0), width, height, quality);
            } finally {
                Marshal.ReleaseComObject(decoder);
                Marshal.ReleaseComObject(inputStream);
            }
        }
示例#4
0
        /// <summary>
        /// Decodes the image in byte[] data, performs the image proccessing, and encodes it to job.Dest
        /// </summary>
        /// <param name="data">The buffer containing the encoded image file</param>
        /// <param name="lData">The number of bytes to read</param>
        /// <param name="job"></param>
        /// <param name="supportsTransparency"></param>
        /// <returns></returns>
        protected virtual RequestedAction BuildJobWic(byte[] data, long lData, ImageJob job, bool supportsTransparency)
        {
            ResizeSettings settings = job.Settings; ResizeSettings q = settings;
            string         path = job.SourcePathData;

            //A list of COM objects to destroy
            List <object> com = new List <object>();

            try {
                //Create the factory
                IWICComponentFactory factory = (IWICComponentFactory) new WICImagingFactory();
                com.Add(factory);

                //Wrap the byte[] with a IWICStream instance
                var streamWrapper = factory.CreateStream();
                streamWrapper.InitializeFromMemory(data, (uint)lData);
                com.Add(streamWrapper);

                var decoder = factory.CreateDecoderFromStream(streamWrapper, null,
                                                              WICDecodeOptions.WICDecodeMetadataCacheOnLoad);
                com.Add(decoder);

                //Figure out which frame to work with
                int frameIndex = 0;
                if (!string.IsNullOrEmpty(q["page"]) && !int.TryParse(q["page"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex))
                {
                    if (!string.IsNullOrEmpty(q["frame"]) && !int.TryParse(q["frame"], NumberStyles.Number, NumberFormatInfo.InvariantInfo, out frameIndex))
                    {
                        frameIndex = 0;
                    }
                }

                //So users can use 1-based numbers
                frameIndex--;

                if (frameIndex > 0)
                {
                    int frameCount = (int)decoder.GetFrameCount(); //Don't let the user go past the end.
                    if (frameIndex >= frameCount)
                    {
                        frameIndex = frameCount - 1;
                    }
                }

                IWICBitmapFrameDecode frame = decoder.GetFrame((uint)Math.Max(0, frameIndex));
                com.Add(frame);



                WICBitmapInterpolationMode interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeFant;
                if ("nearest".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase))
                {
                    interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeNearestNeighbor;
                }
                if ("bicubic".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase))
                {
                    interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeCubic;
                }
                if ("linear".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase))
                {
                    interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear;
                }
                if ("nearestneighbor".Equals(settings["w.filter"], StringComparison.OrdinalIgnoreCase))
                {
                    interpolationMode = WICBitmapInterpolationMode.WICBitmapInterpolationModeLinear;
                }

                //Find the original image size
                uint origWidth, origHeight;
                frame.GetSize(out origWidth, out origHeight);
                Size orig = new Size((int)origWidth, (int)origHeight);

                Guid pixelFormat;
                frame.GetPixelFormat(out pixelFormat);
                //Calculate the new size of the image and the canvas.
                ImageState state = new ImageState(settings, orig, true);
                c.CurrentImageBuilder.Process(state);


                Rectangle imageDest = PolygonMath.ToRectangle(PolygonMath.GetBoundingBox(state.layout["image"]));


                IWICBitmapSource imageData = frame;
                //Are we cropping? then daisy-chain a clipper
                if (state.copyRect.Left != 0 || state.copyRect.Top != 0 || state.copyRect.Width != state.originalSize.Width || state.copyRect.Height != state.originalSize.Height)
                {
                    //Cropping is absurdly slow... 4x slower than resizing!
                    //Cropping after resizing (unintuitively) is faster.
                    if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height)
                    {
                        double sx = (double)imageDest.Width / (double)state.copyRect.Width;
                        double sy = (double)imageDest.Height / (double)state.copyRect.Height;
                        uint   uncroppedDestWidth  = (uint)Math.Round(sx * state.originalSize.Width);
                        uint   uncroppedDestHeight = (uint)Math.Round(sy * state.originalSize.Height);

                        var scaler = factory.CreateBitmapScaler();
                        scaler.Initialize(imageData, uncroppedDestWidth, uncroppedDestHeight, interpolationMode);
                        com.Add(scaler);

                        //TODO: cropping is not consistent with GDI.
                        var clipper = factory.CreateBitmapClipper();
                        clipper.Initialize(scaler, new WICRect {
                            X      = (int)Math.Floor((double)state.copyRect.X * sx),
                            Y      = (int)Math.Floor((double)state.copyRect.Y * sy),
                            Width  = imageDest.Width,
                            Height = imageDest.Height
                        });
                        com.Add(clipper);
                        imageData = clipper;
                    }
                    else
                    {
                        var clipper = factory.CreateBitmapClipper();
                        clipper.Initialize(imageData, new WICRect {
                            X = (int)state.copyRect.X, Y = (int)state.copyRect.Y, Width = (int)state.copyRect.Width, Height = (int)state.copyRect.Height
                        });
                        com.Add(clipper);
                        imageData = clipper;
                    }
                    //If we're scaling but not cropping.
                }
                else if (imageDest.Width != state.originalSize.Width || imageDest.Height != state.originalSize.Height)
                {
                    var scaler = factory.CreateBitmapScaler();
                    scaler.Initialize(imageData, (uint)imageDest.Width, (uint)imageDest.Height, interpolationMode);
                    com.Add(scaler);
                    imageData = scaler;
                }



                //Are we padding? Then we have to do an intermediate write.
                if (state.destSize.Width != imageDest.Width || state.destSize.Height != imageDest.Height)
                {
                    byte[] bgcolor = ConversionUtils.ConvertColor(job.Settings.BackgroundColor, pixelFormat);

                    for (int i = 0; i < bgcolor.Length; i++)
                    {
                        bgcolor[i] = 255;                                      //White
                    }
                    var padder = new WicBitmapPadder(imageData, imageDest.X, imageDest.Y, state.destSize.Width - (imageDest.X + imageDest.Width), state.destSize.Height - (imageDest.Y + imageDest.Height), bgcolor, null);
                    imageData = padder;
                }

                //Now encode imageData and be done with it...
                return(Encode(factory, imageData, imageDest.Size, job));
            } finally {
                //Manually cleanup all the com reference counts, aggressively
                while (com.Count > 0)
                {
                    Marshal.ReleaseComObject(com[com.Count - 1]); //In reverse order, so no item is ever deleted out from under another.
                    com.RemoveAt(com.Count - 1);
                }
            }
        }