• 图片缩放的相关处理


    图片缩放的相关处理

    最近自己做的点东西上用到了图片的处理,不过没有找到合适的图片处理相关算法,倒是找到了几个获取缩略图的算法。代码不长,简单看了看原理也比较简单(其实不是简单是C#的封装的太多了,所以显得比较简单)。既然没有相关的统一调用的代码,索性,我来整理一套相关的处理代码然后公开出来吧。

    图片处理的相关分析

    其实我要用的图片处理非常简单,就是简单的压缩一下图片。然后把图片设置到对应大小而已。但是对于设置的方式,C#基础的函数中使用的Rect范围设置。这个范围设置计算起来可能相对头疼一些。所以我在考虑要不要让调用者在忽略Rect这个参数的情况愉快的调用接口呢?于是乎,我定义了几个图片缩放类型(Full、Zoom、Overflow、Original)。然后默认的让原始图片的中心点与输出图片的中心点对齐。然后根据缩放类型来对图片进行不同的缩放模式。

    缩放模式

    1. Full:让图片放弃原来的比例,直接按照目标数据进行拉伸
    2. Zoom:让图片保持原有比例,并且保证原始图片在目标图片的正中央,没有图片的位置保留米白色
    3. Original:让图片保持原来的大小,输出图片类似于裁剪中间位置某个范围的图片
    4. Overflow:让图片保持原来的比例,并且保证输目标是被图片填满的不留空白

    调用的范例

    ImageHelper.GetInstance().ImageCompress(InputFile, Path.Combine(OutPutPath, item_file), new System.Drawing.Size(500, 300), ImageZoomType.Full, 50);

    样品展示

    原始图片

    Full 300*500 

     

    Full 500 * 300

     

    Original 300 * 500

     

    Original 500 * 300

     

    Overflow 300 * 500

     

    Overflow 500 * 300

     

    Zoom 300 * 500

     

    Zoom 500 * 300

    存在的不足

    1. 压缩没有独到的技术
    2. 目前只支持JPEG格式的图片
    3. 部分图片进行缩放之后会留下一个1像素浅浅的边

    后续的内容

    图片处理不光是缩放,还有其他的很多东西比较实用(截图、压缩、按高缩放、按宽缩放、添加水印、添加隐藏水印),我准备把图片常用的相关处理。整理成一个帮助类,方便迁入到各个项目中去。

    所以我建立了一个专门的图片处理的开源项目方便后续功能加入,地址如下:http://git.oschina.net/anxin1225/ImageCompress

     

    压缩相关的代码

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Drawing.Imaging;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ImageCompress
    {
        public struct AnchorPoint
        {
            //public AnchorPoint() : this(0, 0) { }
            public AnchorPoint(double x, double y)
            {
                X = x;
                Y = y;
            }
    
            public double X, Y;
        }
    
        public enum ImageZoomType
        {
            Full,
            Zoom,
            Overflow,
            Original,
        }
    
        public delegate void ImageHandle(Image image, Bitmap bitmap);
    
        public class ImageHelper
        {
            private ImageHelper() { }
    
            private static ImageHelper _image_helper = null;
            private Dictionary<ImageZoomType, ImageHandle> _name_to_handle = new Dictionary<ImageZoomType, ImageHandle>();
    
            public static ImageHelper GetInstance()
            {
                if (_image_helper == null)
                {
                    _image_helper = new ImageHelper();
    
                    //填满
                    _image_helper._name_to_handle[ImageZoomType.Full] = (image, bitmap) =>
                    {
                        _image_helper.DrawImage(image, bitmap, new Rectangle(new Point(0, 0), bitmap.Size));
                    };
    
                    //原始
                    _image_helper._name_to_handle[ImageZoomType.Original] = (image, bitmap) =>
                    {
                        _image_helper.DrawImage(image, bitmap, 1, new AnchorPoint(0.5, 0.5), new AnchorPoint(0.5, 0.5));
                    };
    
                    //溢出
                    _image_helper._name_to_handle[ImageZoomType.Overflow] = (image, bitmap) =>
                    {
                        float proportion_x = (float)bitmap.Width / image.Width;
                        float proportion_y = (float)bitmap.Height / image.Height;
                        _image_helper.DrawImage(image, bitmap, proportion_x > proportion_y ? proportion_x : proportion_y, new AnchorPoint(0.5, 0.5), new AnchorPoint(0.5, 0.5));
                    };
    
                    //缩放
                    _image_helper._name_to_handle[ImageZoomType.Zoom] = (image, bitmap) =>
                    {
                        float proportion_x = (float)bitmap.Width / image.Width;
                        float proportion_y = (float)bitmap.Height / image.Height;
                        _image_helper.DrawImage(image, bitmap, proportion_x < proportion_y ? proportion_x : proportion_y, new AnchorPoint(0.5, 0.5), new AnchorPoint(0.5, 0.5));
                    };
                }
    
                return _image_helper;
            }
    
            /// <summary>
            /// 压缩图片
            /// </summary>
            /// <param name="source_path">源数据位置</param>
            /// <param name="save_path">保存数据位置</param>
            /// <param name="save_size">保存图片大小</param>
            /// <param name="ztype">缩放模式</param>
            /// <param name="flag">图片保存品质</param>
            /// <returns>是否完成压缩</returns>
            public bool ImageCompress(string source_path, string save_path, Size save_size, ImageZoomType ztype, int flag)
            {
                bool success = false;
    
                Image source = null;
    
                while (true)
                {
                    source = LoadImage(source_path);
                    if (source == null)
                        break;
    
                    Bitmap bitmap = new Bitmap(save_size.Width, save_size.Height);
    
                    if (_name_to_handle.ContainsKey(ztype))
                    {
                        _name_to_handle[ztype](source, bitmap);
                    }
                    else
                    {
                        break;
                    }
    
                    success = SaveImage(bitmap, save_path, source.RawFormat, flag);
                    break;
                }
    
                if (source != null)
                    source.Dispose();
    
                return success;
            }
    
            public Image LoadImage(string source_path)
            {
                Image image = null;
                while (true)
                {
                    if (!File.Exists(source_path))
                        break;
    
                    try
                    {
                        image = Image.FromFile(source_path);
                    }
                    catch
                    {
                        break;
                    }
    
                    break;
                }
    
                return image;
            }
    
            /// <summary>
            /// 将BitMap保存到磁盘上
            /// </summary>
            /// <param name="image">需要保存的图片</param>
            /// <param name="save_path">保存的路径</param>
            /// <param name="format">保存格式</param>
            /// <param name="flag">保存质量</param>
            /// <returns></returns>
            public bool SaveImage(Bitmap image, string save_path, ImageFormat format, int flag)
            {
                //以下代码为保存图片时,设置压缩质量  
                EncoderParameters ep = new EncoderParameters();
                long[] qy = new long[1];
                qy[0] = flag;//设置压缩的比例1-100  
                EncoderParameter eParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, qy);
                ep.Param[0] = eParam;
                try
                {
                    ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
                    ImageCodecInfo jpegICIinfo = null;
                    for (int x = 0; x < arrayICI.Length; x++)
                    {
                        if (arrayICI[x].FormatDescription.Equals("JPEG"))
                        {
                            jpegICIinfo = arrayICI[x];
                            break;
                        }
                    }
                    if (jpegICIinfo != null)
                    {
                        image.Save(save_path, jpegICIinfo, ep);//dFile是压缩后的新路径  
                    }
                    else
                    {
                        image.Save(save_path, format);
                    }
                    return true;
                }
                catch
                {
                    return false;
                }
                finally
                {
                    image.Dispose();
                }
            }
    
            /// <summary>
            /// 画图
            /// </summary>
            /// <param name="source">原始图像</param>
            /// <param name="output">输出图像</param>
            /// <param name="souce_scale">原始图像的缩放值</param>
            /// <param name="souce_anchor"></param>
            /// <param name="graphics_anchor"></param>
            public void DrawImage(Image source, Bitmap output, float souce_scale, AnchorPoint souce_anchor, AnchorPoint graphics_anchor)
            {
                DrawImage(source, output, souce_scale, souce_anchor, new Point((int)(output.Width * graphics_anchor.X), (int)(output.Height * graphics_anchor.Y)));
            }
    
            /// <summary>
            /// 画图
            /// </summary>
            /// <param name="source">原始图像</param>
            /// <param name="output">输出凸显</param>
            /// <param name="source_scale">图像的所放值</param>
            /// <param name="source_anchor">源图像锚点</param>
            /// <param name="souce_point">图像位置</param>
            public void DrawImage(Image source, Bitmap output, float source_scale, AnchorPoint source_anchor, Point souce_point)
            {
                var pic_po = new Point((int)(souce_point.X - source.Size.Width * source_scale * source_anchor.X), (int)(souce_point.Y - source.Size.Height * source_scale * source_anchor.Y));
                DrawImage(source, output, new Rectangle(pic_po, new Size((int)(source.Width * source_scale), (int)(source.Height * source_scale))));
            }
    
            /// <summary>
            /// 画图
            /// </summary>
            /// <param name="source"></param>
            /// <param name="output"></param>
            /// <param name="rect"></param>
            public void DrawImage(Image source, Bitmap output, Rectangle rect)
            {
                Graphics g = Graphics.FromImage(output);
                g.Clear(Color.WhiteSmoke);
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImage(source, rect, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel);
                g.Dispose();
            }
        }
    }
    

      

     

    PS:为了美观本文中的原始图片并不是原始图片,因为原始图片太大了。会造成页面滑动,所以我上传了一张较小的图片。Git的图片则是原始的图片

  • 相关阅读:
    1-6注册View Prism官网案例学习
    MVVM复习
    Prism常用类库翻译
    SqlHelper
    ADO.NET复习
    C#复习思维导图
    网络通信基础知识1
    网络通信
    Linux-线程同步之互斥锁
    linux-线程同步之信号量
  • 原文地址:https://www.cnblogs.com/anxin1225/p/5895869.html
Copyright © 2020-2023  润新知