1. 程式人生 > >asp.net圖片後臺壓縮保存到服務器

asp.net圖片後臺壓縮保存到服務器

背景色 畫板 bsp region 配置文件 oms pac code 模式

#region << 版 本 註 釋 >>
/****************************************************
* 文 件 名:ImageHelper
* Copyright(c) www.ITdos.com
* CLR 版本: 4.0.30319.17929
* 創 建 人:ITdos
* 電子郵箱:[email protected]
* 創建日期:2010/04/01 11:00:49
* 文件描述:
******************************************************
* 修 改 人:
* 修改日期:
* 備註描述:
*******************************************************/
#endregion
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;

namespace MaoLiao.Common
{
/// <summary>
/// 圖片水印處理類
/// </summary>
public class Image_Helper
{
#region 配置文件

/// <summary>
/// 生成縮略圖的模式, WH-指定寬高縮放(可能變形) W-指定寬,高按比例 H-指定高,寬按比例 CUT-指定高寬裁減(不變形,推薦用這個)。
/// </summary>
public enum ThumbnailModeOption : byte
{
/// <summary>
/// 指定寬高縮放(可能變形)
/// </summary>
WH,
/// <summary>
/// 指定寬,高按比例
/// </summary>
W,
/// <summary>
/// 指定高,寬按比例
/// </summary>
H,
/// <summary>
/// 指定高寬裁減(不變形,推薦用這個)
/// </summary>
CUT,
/// <summary>
/// 自定義(如果寬高超過自定義的就按照指定寬高裁剪)
/// </summary>
CUSTOM
}

/// <summary>
/// 加圖片水印的位置,TopLeft-左上角 TopCenter-上中間 TopRight-右上角 BottomLeft-左下角 BottomCenter-下中間 右下角-右下角 Middle-正中間。
/// </summary>
public enum WaterPositionOption : byte
{
/// <summary>
/// 左上角
/// </summary>
LeftTop,
/// <summary>
/// 上中間
/// </summary>
CenterTop,
/// <summary>
/// 右上角
/// </summary>
RightTop,
/// <summary>
/// 左下角
/// </summary>
LeftBottom,
/// <summary>
/// 下中間
/// </summary>
CenterBottom,
/// <summary>
/// 右下角
/// </summary>
RightBottom,
/// <summary>
/// 正中間
/// </summary>
Middle
}

/// <summary>
/// 獲取圖片格式。
/// </summary>
/// <Param name="fileName">文件名</Param>
/// <returns></returns>
public static ImageFormat GetImageFormat(string fileName)
{
string extension = fileName.Substring(fileName.LastIndexOf(".")).Trim().ToLower();

switch (extension)
{
case ".jpg":
return System.Drawing.Imaging.ImageFormat.Jpeg;
case ".jpeg":
return System.Drawing.Imaging.ImageFormat.Jpeg;
case ".gif":
return System.Drawing.Imaging.ImageFormat.Gif;
case ".png":
return System.Drawing.Imaging.ImageFormat.Png;
case ".bmp":
return System.Drawing.Imaging.ImageFormat.Bmp;
case ".ico":
return System.Drawing.Imaging.ImageFormat.Icon;
default:
goto case ".jpg";
}
}

#endregion

/// <summary>
/// 加水印圖片並保存。(最好不要單獨調用此接口)
/// </summary>
/// <Param name="originalImageStream">Stream</Param>
/// <Param name="strFileName">源圖路徑(物理路徑)</Param>
/// <Param name="savePath">圖片保存路徑(物理路徑)</Param>
/// <Param name="waterPath">水印圖路徑(物理路徑)</Param>
/// <Param name="edge">水印圖離原圖邊界的距離</Param>
/// <Param name="position">加圖片水印的位置</Param>
/// <returns>是否成功</returns>
private static bool MakeWaterImage(Stream originalImageStream, string strFileName, string savePath, string waterPath, int edge, WaterPositionOption position)
{
bool success = false;

int x = 0;
int y = 0;
Image waterImage = null;
Image image = null;
Bitmap bitmap = null;
Graphics graphics = null;

try
{
//加載原圖
image = Image.FromStream(originalImageStream);
//加載水印圖
waterImage = Image.FromFile(waterPath);
bitmap = new Bitmap(image);
graphics = Graphics.FromImage(bitmap);

int newEdge = edge;
if (newEdge >= image.Width + waterImage.Width) newEdge = 10;

switch (position)
{
case WaterPositionOption.LeftTop:
x = newEdge;
y = newEdge;
break;
case WaterPositionOption.CenterTop:
x = (image.Width - waterImage.Width) / 2;
y = newEdge;
break;
case WaterPositionOption.RightTop:
x = image.Width - waterImage.Width - newEdge;
y = newEdge;
break;
case WaterPositionOption.LeftBottom:
x = newEdge;
y = image.Height - waterImage.Height - newEdge;
break;
case WaterPositionOption.CenterBottom:
x = (image.Width - waterImage.Width) / 2;
y = image.Height - waterImage.Height - newEdge;
break;
case WaterPositionOption.RightBottom:
x = image.Width - waterImage.Width - newEdge;
y = image.Height - waterImage.Height - newEdge;
break;
case WaterPositionOption.Middle:
x = (image.Width - waterImage.Width) / 2;
y = (image.Height - waterImage.Height) / 2;
break;
default:
goto case WaterPositionOption.RightBottom;
}

// 畫水印圖片
graphics.DrawImage(waterImage, new Rectangle(x, y, waterImage.Width, waterImage.Height), 0, 0, waterImage.Width, waterImage.Height, GraphicsUnit.Pixel);

// 關閉打開著的文件並保存(覆蓋)新圖片
originalImageStream.Close();
bitmap.Save(savePath, GetImageFormat(strFileName));

success = true;
}
catch (Exception ex)
{
success = false;
throw;
//throw new Exception(ex.Message.Replace("‘", " ").Replace("\n", " ").Replace("\\", "/"));
}
finally
{
if (graphics != null) graphics.Dispose();
if (bitmap != null) bitmap.Dispose();
if (image != null) image.Dispose();
if (waterImage != null) waterImage.Dispose();
}

return success;
}

/// <summary>
/// 生成縮略圖並保存。
/// </summary>
/// <Param name="originalImageStream">Stream</Param>
/// <Param name="strFileName">源圖路徑(物理路徑)</Param>
/// <Param name="thumbnailPath">縮略圖路徑(物理路徑)</Param>
/// <Param name="maxWidth">縮略圖最大寬度</Param>
/// <Param name="maxheight">縮略圖最大高度</Param>
/// <Param name="mode">生成縮略圖的方式</Param>
/// <returns>是否成功</returns>
public static bool MakeThumbnail(Stream originalImageStream, string strFileName, string thumbnailPath, int maxWidth, int maxheight, ThumbnailModeOption mode)
{
bool success = false;

int x = 0;
int y = 0;
int toW = maxWidth;
int toH = maxheight;
Image image = null;
Image bitmap = null;
Graphics graphics = null;
try
{
image = Image.FromStream(originalImageStream);
int w = image.Width;
int h = image.Height;

/*上傳相冊最小尺寸*/
if (w <= 500 || h <= 500 || w >= 4080) { return false; }

#region upload Mode Select

switch (mode)
{
case ThumbnailModeOption.WH:
break;
case ThumbnailModeOption.W:
if (w < maxWidth)
{
toW = w;
toH = h;
}
else
{
toH = h * maxWidth / w;
}
break;
case ThumbnailModeOption.H:
if (h < maxheight)
{
toW = w;
toH = h;
}
else
{
toW = w * maxheight / h;
}
break;
case ThumbnailModeOption.CUT:
if (((double)w / (double)h) > ((double)toW / (double)toH))
{
w = h * toW / toH;
y = 0;
x = (image.Width - w) / 2;
}
else
{
h = w * toH / toW;
x = 0;
y = (image.Height - h) / 2;
}
break;
case ThumbnailModeOption.CUSTOM:
if (h <= maxheight)
{
toW = w;
toH = h;
}
else
{
// LogHelper.WriteLog(LogFile.Debug, "【上傳圖片尺寸不對】w:{0},h:{1}", w, h);
goto case ThumbnailModeOption.CUT;
}
break;
default:
goto case ThumbnailModeOption.CUT;
}
#endregion

bitmap = new Bitmap(toW, toH);
graphics = Graphics.FromImage(bitmap);
graphics.InterpolationMode = InterpolationMode.High; //設置高質量,低速度呈現平滑程度
graphics.SmoothingMode = SmoothingMode.HighQuality; //清空畫布並以透明背景色填充
graphics.Clear(Color.Transparent);
// 在指定位置並且按指定大小繪制原圖片的指定部分
graphics.DrawImage(image, new Rectangle(0, 0, toW, toH), new Rectangle(x, y, w, h), GraphicsUnit.Pixel);

// 打文字水印
//Brush b = new SolidBrush(Color.White);
//Font f = new Font("宋體", 15);
//graphics.DrawString("@喵播直播", f, b, new Rectangle(0, 0, toW / 2, toH / 2 + 10));

// 保存縮略圖
//bitmap.Save(thumbnailPath, GetImageFormat(strFileName));
bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
success = true;
}
catch (Exception ex)
{
success = false;
throw ex;
}
finally
{
if (graphics != null) graphics.Dispose();
if (bitmap != null) bitmap.Dispose();
if (image != null) image.Dispose();
}
return success;
}

/// <summary>
/// 生成縮略圖並打水印再保存。
/// </summary>
/// <Param name="originalImageStream">Stream</Param>
/// <Param name="strFileName">源圖路徑(物理路徑)</Param>
/// <Param name="thumbnailPath">縮略圖路徑(物理路徑)</Param>
/// <Param name="maxWidth">縮略圖最大寬度</Param>
/// <Param name="maxheight">縮略圖最大高度</Param>
/// <Param name="mode">生成縮略圖的方式</Param>
/// <Param name="waterPath">水印圖路徑(物理路徑)</Param>
/// <Param name="edge">水印圖離原圖邊界的距離</Param>
/// <Param name="position">加圖片水印的位置</Param>
/// <returns>是否成功</returns>
public static bool MakeThumbnailWater(Stream originalImageStream, string strFileName, string thumbnailPath, int maxWidth, int maxheight, ThumbnailModeOption mode, string waterPath, int edge, WaterPositionOption position)
{
bool success = false;
try
{
// 生成縮略圖
MakeThumbnail(originalImageStream, strFileName, thumbnailPath, maxWidth, maxheight, mode);
Stream stream = File.Open(thumbnailPath, FileMode.Open);
//打水印
MakeWaterImage(stream, strFileName, thumbnailPath, waterPath, edge, position);
success = true;
}
catch (Exception ex)
{
success = false;
throw;
}
return success;
}

/// <summary>
/// 馬賽克處理
/// </summary>
/// <param name="bitmap"></param>
/// <param name="effectWidth"> 影響範圍 每一個格子數 </param>
/// <returns></returns>
public static Bitmap AdjustTobMosaic(System.Drawing.Bitmap bitmap, int effectWidth)
{
// 差異最多的就是以照一定範圍取樣 玩之後直接去下一個範圍
for (int heightOfffset = 0; heightOfffset < bitmap.Height; heightOfffset += effectWidth)
{
for (int widthOffset = 0; widthOffset < bitmap.Width; widthOffset += effectWidth)
{
int avgR = 0, avgG = 0, avgB = 0;
int blurPixelCount = 0;

for (int x = widthOffset; (x < widthOffset + effectWidth && x < bitmap.Width); x++)
{
for (int y = heightOfffset; (y < heightOfffset + effectWidth && y < bitmap.Height); y++)
{
System.Drawing.Color pixel = bitmap.GetPixel(x, y);

avgR += pixel.R;
avgG += pixel.G;
avgB += pixel.B;

blurPixelCount++;
}
}

// 計算範圍平均
avgR = avgR / blurPixelCount;
avgG = avgG / blurPixelCount;
avgB = avgB / blurPixelCount;


// 所有範圍內都設定此值
for (int x = widthOffset; (x < widthOffset + effectWidth && x < bitmap.Width); x++)
{
for (int y = heightOfffset; (y < heightOfffset + effectWidth && y < bitmap.Height); y++)
{

System.Drawing.Color newColor = System.Drawing.Color.FromArgb(avgR, avgG, avgB);
bitmap.SetPixel(x, y, newColor);
}
}
}
}

return bitmap;
}

#region 圖片壓縮

//生成縮略圖函數
//順序參數:源圖文件流、縮略圖存放地址、模版寬、模版高
//註:縮略圖大小控制在模版區域內
public static void MakeSmallImg(Stream fromFileStream, string fileSaveUrl, System.Double templateWidth, System.Double templateHeight)
{
//從文件取得圖片對象,並使用流中嵌入的顏色管理信息
System.Drawing.Image myImage = System.Drawing.Image.FromStream(fromFileStream, true);
//縮略圖寬、高
System.Double newWidth = myImage.Width, newHeight = myImage.Height;
//寬大於模版的橫圖
if (myImage.Width > myImage.Height || myImage.Width == myImage.Height)
{
if (myImage.Width > templateWidth)
{
//寬按模版,高按比例縮放
newWidth = templateWidth;
newHeight = myImage.Height * (newWidth / myImage.Width);
}
}
//高大於模版的豎圖
else
{
if (myImage.Height > templateHeight)
{
//高按模版,寬按比例縮放
newHeight = templateHeight;
newWidth = myImage.Width * (newHeight / myImage.Height);
}
}
//取得圖片大小
System.Drawing.Size mySize = new Size((int)newWidth, (int)newHeight);
//新建一個bmp圖片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(mySize.Width, mySize.Height);
//新建一個畫板
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);
//設置高質量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//設置高質量,低速度呈現平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//清空一下畫布
g.Clear(Color.White);
//在指定位置畫圖
g.DrawImage(myImage, new Rectangle(0, 0, bitmap.Width, bitmap.Height), new Rectangle(0, 0, myImage.Width, myImage.Height), GraphicsUnit.Pixel);
///文字水印
//System.Drawing.Graphics G = System.Drawing.Graphics.FromImage(bitmap);
//System.Drawing.Font f = new Font("宋體", 13);
//System.Drawing.Brush b = new SolidBrush(Color.Black);
//G.DrawString("9158直播", f, b, 10, 10);
//G.Dispose();
///圖片水印
//System.Drawing.Image copyImage = System.Drawing.Image.FromFile(System.Web.HttpContext.Current.Server.MapPath("pic/1.gif"));
//Graphics a = Graphics.FromImage(bitmap);
//a.DrawImage(copyImage, new Rectangle(bitmap.Width-copyImage.Width,bitmap.Height-copyImage.Height,copyImage.Width, copyImage.Height),0,0, copyImage.Width, copyImage.Height, GraphicsUnit.Pixel);
//copyImage.Dispose();
//a.Dispose();
//copyImage.Dispose();
//保存縮略圖
bitmap.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
g.Dispose();
myImage.Dispose();
bitmap.Dispose();
}

#endregion
#region 無損壓縮圖片
/// <summary>
/// 無損壓縮圖片
/// </summary>
/// <param name="sFile">原圖片地址</param>
/// <param name="dFile">壓縮後保存圖片地址</param>
/// <param name="flag">壓縮質量(數字越小壓縮率越高)1-100</param>
/// <param name="size">壓縮後圖片的最大大小</param>
/// <param name="sfsc">是否是第一次調用</param>
/// <returns></returns>
public static bool CompressImage(string sFile, string dFile, int flag = 95, int size = 250, bool sfsc = true)
{
// Image iSource = Image.FromStream(sFile.InputStream);
// System.Drawing.Image myImage = System.Drawing.Image.FromStream(fromFileStream, true);
Image iSource = Image.FromFile(sFile);
ImageFormat tFormat = iSource.RawFormat;
//如果是第一次調用,原始圖像的大小小於要壓縮的大小,則直接復制文件,並且返回true


FileInfo firstFileInfo = new FileInfo(sFile);
if (sfsc == true && firstFileInfo.Length < size * 1024)
{
firstFileInfo.CopyTo(dFile);
return true;
}

int dHeight = iSource.Height / 2;
int dWidth = iSource.Width / 2;
int sW = 0, sH = 0;
//按比例縮放
Size tem_size = new Size(iSource.Width, iSource.Height);
if (tem_size.Width > dHeight || tem_size.Width > dWidth)
{
if ((tem_size.Width * dHeight) > (tem_size.Width * dWidth))
{
sW = dWidth;
sH = (dWidth * tem_size.Height) / tem_size.Width;
}
else
{
sH = dHeight;
sW = (tem_size.Width * dHeight) / tem_size.Height;
}
}
else
{
sW = tem_size.Width;
sH = tem_size.Height;
}

Bitmap ob = new Bitmap(dWidth, dHeight);
Graphics g = Graphics.FromImage(ob);

g.Clear(Color.WhiteSmoke);
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

g.DrawImage(iSource, new Rectangle((dWidth - sW) / 2, (dHeight - sH) / 2, sW, sH), 0, 0, iSource.Width, iSource.Height, GraphicsUnit.Pixel);

g.Dispose();

//以下代碼為保存圖片時,設置壓縮質量
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)
{
ob.Save(dFile, jpegICIinfo, ep);//dFile是壓縮後的新路徑
FileInfo fi = new FileInfo(dFile);
if (fi.Length > 1024 * size)
{
flag = flag - 10;
CompressImage(sFile, dFile, flag, size, false);
}
}
else
{
ob.Save(dFile, tFormat);
//LogHelper.Log(LogFile.Temp, "【保存圖片結束時間】", "", "", "【URLIMGS42323】" + DateTime.Now + "--");
}
return true;
}
catch
{
return false;
}
finally
{
iSource.Dispose();
ob.Dispose();
}
}
#endregion

}
}

asp.net圖片後臺壓縮保存到服務器