Esempio n. 1
0
 public Image Apply(Image sourceImage, Matrix matrix)
 {
     using (WuQuantizer quantizer = new WuQuantizer((Bitmap)sourceImage))
     {
         int colorCount = quantizer.GetColorCount();
         if (colorCount > Colors)
         {
             try
             {
                 return quantizer.GetQuantizedImage(Colors);
             }
             catch (Exception e)
             {
                 LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
             }
         }
     }
     return null;
 }
        /// <summary>
        /// Create an image from a surface with the settings from the output settings applied
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="outputSettings"></param>
        /// <param name="imageToSave"></param>
        /// <returns>true if the image must be disposed</returns>
        public static bool CreateImageFromSurface(ISurface surface, SurfaceOutputSettings outputSettings, out Image imageToSave)
        {
            bool        disposeImage = false;
            ImageFormat imageFormat  = null;

            switch (outputSettings.Format)
            {
            case OutputFormat.bmp:
                imageFormat = ImageFormat.Bmp;
                break;

            case OutputFormat.gif:
                imageFormat = ImageFormat.Gif;
                break;

            case OutputFormat.jpg:
                imageFormat = ImageFormat.Jpeg;
                break;

            case OutputFormat.tiff:
                imageFormat = ImageFormat.Tiff;
                break;

            case OutputFormat.greenshot:
            case OutputFormat.png:
            default:
                imageFormat = ImageFormat.Png;
                break;
            }

            if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly)
            {
                // We save the image of the surface, this should not be disposed
                imageToSave = surface.Image;
            }
            else
            {
                // We create the export image of the surface to save
                imageToSave  = surface.GetImageForExport();
                disposeImage = true;
            }

            // The following block of modifications should be skipped when saving the greenshot format, no effects or otherwise!
            if (outputSettings.Format != OutputFormat.greenshot)
            {
                Image tmpImage;
                if (outputSettings.Effects != null && outputSettings.Effects.Count > 0)
                {
                    // apply effects, if there are any
                    Point ignoreOffset;
                    tmpImage = ImageHelper.ApplyEffects((Bitmap)imageToSave, outputSettings.Effects, out ignoreOffset);
                    if (tmpImage != null)
                    {
                        if (disposeImage)
                        {
                            imageToSave.Dispose();
                        }
                        imageToSave  = tmpImage;
                        disposeImage = true;
                    }
                }

                // check for color reduction, forced or automatically, only when the DisableReduceColors is false
                if (!outputSettings.DisableReduceColors && (conf.OutputFileAutoReduceColors || outputSettings.ReduceColors))
                {
                    bool isAlpha = Image.IsAlphaPixelFormat(imageToSave.PixelFormat);
                    if (outputSettings.ReduceColors || (!isAlpha && conf.OutputFileAutoReduceColors))
                    {
                        using (WuQuantizer quantizer = new WuQuantizer((Bitmap)imageToSave))
                        {
                            int colorCount = quantizer.GetColorCount();
                            LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
                            if (outputSettings.ReduceColors || colorCount < 256)
                            {
                                try
                                {
                                    LOG.Info("Reducing colors on bitmap to 256.");
                                    tmpImage = quantizer.GetQuantizedImage(256);
                                    if (disposeImage)
                                    {
                                        imageToSave.Dispose();
                                    }
                                    imageToSave = tmpImage;
                                    // Make sure the "new" image is disposed
                                    disposeImage = true;
                                }
                                catch (Exception e)
                                {
                                    LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
                                }
                            }
                        }
                    }
                    else if (isAlpha && !outputSettings.ReduceColors)
                    {
                        LOG.Info("Skipping 'optional' color reduction as the image has alpha");
                    }
                }
            }
            return(disposeImage);
        }
Esempio n. 3
0
        /// <summary>
        /// Create an image from a surface with the settings from the output settings applied
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="outputSettings"></param>
        /// <param name="imageToSave"></param>
        /// <returns>true if the image must be disposed</returns>
        public static bool CreateImageFromSurface(ISurface surface, SurfaceOutputSettings outputSettings, out Image imageToSave)
        {
            bool disposeImage = false;

            if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly)
            {
                // We save the image of the surface, this should not be disposed
                imageToSave = surface.Image;
            }
            else
            {
                // We create the export image of the surface to save
                imageToSave  = surface.GetImageForExport();
                disposeImage = true;
            }

            // The following block of modifications should be skipped when saving the greenshot format, no effects or otherwise!
            if (outputSettings.Format == OutputFormat.greenshot)
            {
                return(disposeImage);
            }
            Image tmpImage;

            if (outputSettings.Effects != null && outputSettings.Effects.Count > 0)
            {
                // apply effects, if there are any
                using (Matrix matrix = new Matrix()) {
                    tmpImage = ImageHelper.ApplyEffects(imageToSave, outputSettings.Effects, matrix);
                }
                if (tmpImage != null)
                {
                    if (disposeImage)
                    {
                        imageToSave.Dispose();
                    }
                    imageToSave  = tmpImage;
                    disposeImage = true;
                }
            }

            // check for color reduction, forced or automatically, only when the DisableReduceColors is false
            if (outputSettings.DisableReduceColors || (!CoreConfig.OutputFileAutoReduceColors && !outputSettings.ReduceColors))
            {
                return(disposeImage);
            }
            bool isAlpha = Image.IsAlphaPixelFormat(imageToSave.PixelFormat);

            if (outputSettings.ReduceColors || (!isAlpha && CoreConfig.OutputFileAutoReduceColors))
            {
                using (var quantizer = new WuQuantizer((Bitmap)imageToSave)) {
                    int colorCount = quantizer.GetColorCount();
                    Log.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
                    if (!outputSettings.ReduceColors && colorCount >= 256)
                    {
                        return(disposeImage);
                    }
                    try {
                        Log.Info("Reducing colors on bitmap to 256.");
                        tmpImage = quantizer.GetQuantizedImage(CoreConfig.OutputFileReduceColorsTo);
                        if (disposeImage)
                        {
                            imageToSave.Dispose();
                        }
                        imageToSave = tmpImage;
                        // Make sure the "new" image is disposed
                        disposeImage = true;
                    } catch (Exception e) {
                        Log.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
                    }
                }
            }
            else if (isAlpha && !outputSettings.ReduceColors)
            {
                Log.Info("Skipping 'optional' color reduction as the image has alpha");
            }
            return(disposeImage);
        }
Esempio n. 4
0
        /// <summary>
        /// Create an image from a surface with the settings from the output settings applied
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="outputSettings"></param>
        /// <param name="imageToSave"></param>
        /// <returns>true if the image must be disposed</returns>
        public static bool CreateImageFromSurface(ISurface surface, SurfaceOutputSettings outputSettings, out Image imageToSave)
        {
            bool disposeImage = false;
            ImageFormat imageFormat = null;
            switch (outputSettings.Format)
            {
                case OutputFormat.bmp:
                    imageFormat = ImageFormat.Bmp;
                    break;
                case OutputFormat.gif:
                    imageFormat = ImageFormat.Gif;
                    break;
                case OutputFormat.jpg:
                    imageFormat = ImageFormat.Jpeg;
                    break;
                case OutputFormat.tiff:
                    imageFormat = ImageFormat.Tiff;
                    break;
                case OutputFormat.greenshot:
                case OutputFormat.png:
                default:
                    imageFormat = ImageFormat.Png;
                    break;
            }

            if (outputSettings.Format == OutputFormat.greenshot || outputSettings.SaveBackgroundOnly)
            {
                // We save the image of the surface, this should not be disposed
                imageToSave = surface.Image;
            }
            else
            {
                // We create the export image of the surface to save
                imageToSave = surface.GetImageForExport();
                disposeImage = true;
            }

            // The following block of modifications should be skipped when saving the greenshot format, no effects or otherwise!
            if (outputSettings.Format != OutputFormat.greenshot)
            {
                Image tmpImage;
                if (outputSettings.Effects != null && outputSettings.Effects.Count > 0)
                {
                    // apply effects, if there are any
                    Point ignoreOffset;
                    tmpImage = ImageHelper.ApplyEffects((Bitmap)imageToSave, outputSettings.Effects, out ignoreOffset);
                    if (tmpImage != null)
                    {
                        if (disposeImage)
                        {
                            imageToSave.Dispose();
                        }
                        imageToSave = tmpImage;
                        disposeImage = true;
                    }
                }

                // check for color reduction, forced or automatically, only when the DisableReduceColors is false
                if (!outputSettings.DisableReduceColors && (conf.OutputFileAutoReduceColors || outputSettings.ReduceColors))
                {
                    bool isAlpha = Image.IsAlphaPixelFormat(imageToSave.PixelFormat);
                    if (outputSettings.ReduceColors || (!isAlpha && conf.OutputFileAutoReduceColors))
                    {
                        using (WuQuantizer quantizer = new WuQuantizer((Bitmap)imageToSave))
                        {
                            int colorCount = quantizer.GetColorCount();
                            LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
                            if (outputSettings.ReduceColors || colorCount < 256)
                            {
                                try
                                {
                                    LOG.Info("Reducing colors on bitmap to 256.");
                                    tmpImage = quantizer.GetQuantizedImage(256);
                                    if (disposeImage)
                                    {
                                        imageToSave.Dispose();
                                    }
                                    imageToSave = tmpImage;
                                    // Make sure the "new" image is disposed
                                    disposeImage = true;
                                }
                                catch (Exception e)
                                {
                                    LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
                                }
                            }
                        }
                    }
                    else if (isAlpha && !outputSettings.ReduceColors)
                    {
                        LOG.Info("Skipping 'optional' color reduction as the image has alpha");
                    }
                }
            }
            return disposeImage;
        }
        /// <summary>
        /// Saves image to stream with specified quality
        /// </summary>
        public static void SaveToStream(Image imageToSave, Stream stream, OutputFormat extension, int quality, bool reduceColors)
        {
            ImageFormat imageFormat = null;
            bool disposeImage = false;

            switch (extension) {
                case OutputFormat.bmp:
                    imageFormat = ImageFormat.Bmp;
                    break;
                case OutputFormat.gif:
                    imageFormat = ImageFormat.Gif;
                    break;
                case OutputFormat.jpg:
                    imageFormat = ImageFormat.Jpeg;
                    break;
                case OutputFormat.png:
                    imageFormat = ImageFormat.Png;
                    break;
                case OutputFormat.tiff:
                    imageFormat = ImageFormat.Tiff;
                    break;
                default:
                    imageFormat = ImageFormat.Png;
                    break;
            }

            // Fix for Bug #3468436, force quantizing when output format is gif as this has only 256 colors!
            if (ImageFormat.Gif.Equals(imageFormat)) {
                reduceColors = true;
            }

            // Removing transparency if it's not supported
            if (imageFormat != ImageFormat.Png) {
                imageToSave = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb);
                disposeImage = true;
            }

            // check for color reduction, forced or automatically
            if (conf.OutputFileAutoReduceColors || reduceColors) {
                WuQuantizer quantizer = new WuQuantizer((Bitmap)imageToSave);
                int colorCount = quantizer.GetColorCount();
                LOG.InfoFormat("Image with format {0} has {1} colors", imageToSave.PixelFormat, colorCount);
                if (reduceColors || colorCount < 256) {
                    try {
                        LOG.Info("Reducing colors on bitmap to 255.");
                        Image tmpImage = quantizer.GetQuantizedImage(255);
                        if (disposeImage) {
                            imageToSave.Dispose();
                        }
                        imageToSave = tmpImage;
                        // Make sure the "new" image is disposed
                        disposeImage = true;
                    } catch (Exception e) {
                        LOG.Warn("Error occurred while Quantizing the image, ignoring and using original. Error: ", e);
                    }
                }
            } else {
                LOG.Info("Skipping color reduction test, OutputFileAutoReduceColors is set to false.");
            }

            try {
                // Create meta-data
                PropertyItem softwareUsedPropertyItem = CreatePropertyItem(PROPERTY_TAG_SOFTWARE_USED, "Greenshot");
                if (softwareUsedPropertyItem != null) {
                    try {
                        imageToSave.SetPropertyItem(softwareUsedPropertyItem);
                    } catch (ArgumentException) {
                        LOG.WarnFormat("Image of type {0} do not support property {1}", imageFormat, softwareUsedPropertyItem.Id);
                    }
                }
                LOG.DebugFormat("Saving image to stream with Format {0} and PixelFormat {1}", imageFormat, imageToSave.PixelFormat);
                if (imageFormat == ImageFormat.Jpeg) {
                    EncoderParameters parameters = new EncoderParameters(1);
                    parameters.Param[0] = new System.Drawing.Imaging.EncoderParameter(Encoder.Quality, quality);
                    ImageCodecInfo[] ies = ImageCodecInfo.GetImageEncoders();
                    imageToSave.Save(stream, ies[1], parameters);
                } else if (imageFormat != ImageFormat.Png && Image.IsAlphaPixelFormat(imageToSave.PixelFormat)) {
                    // No transparency in target format
                    using (Bitmap tmpBitmap = ImageHelper.Clone(imageToSave, PixelFormat.Format24bppRgb)) {
                        tmpBitmap.Save(stream, imageFormat);
                    }
                } else {
                    imageToSave.Save(stream, imageFormat);
                }
            } finally {
                // cleanup if needed
                if (disposeImage && imageToSave != null) {
                    imageToSave.Dispose();
                }
            }
        }