程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 圖片縮放的相關處理,圖片縮放相關處理

圖片縮放的相關處理,圖片縮放相關處理

編輯:關於.NET

圖片縮放的相關處理,圖片縮放相關處理


圖片縮放的相關處理

最近自己做的點東西上用到了圖片的處理,不過沒有找到合適的圖片處理相關算法,倒是找到了幾個獲取縮略圖的算法。代碼不長,簡單看了看原理也比較簡單(其實不是簡單是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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved