C#图片截取压缩(百分比压缩/大小压缩)实现代码
程序员文章站
2024-03-04 11:17:47
前端时间朋友要传一些图片给我,全是大图,考虑到网速的限制,让他处理下图片大小再给我,这厮居然不知道用什么工具.为了娱乐写了个截取图片和压缩图片你的小工具 1.按照百分比截图...
前端时间朋友要传一些图片给我,全是大图,考虑到网速的限制,让他处理下图片大小再给我,这厮居然不知道用什么工具.
为了娱乐写了个截取图片和压缩图片你的小工具
1.按照百分比截图
view code
/// <summary>
/// 按照比例缩小图片
/// </summary>
/// <param name="srcimage">要缩小的图片</param>
/// <param name="percent">缩小比例</param>
/// <returns>缩小后的结果</returns>
public static bitmap percentimage(image srcimage, double percent)
{
// 缩小后的高度
int newh = int.parse(math.round(srcimage.height * percent).tostring());
// 缩小后的宽度
int neww = int.parse(math.round(srcimage.width * percent).tostring());
try
{
// 要保存到的图片
bitmap b = new bitmap(neww, newh);
graphics g = graphics.fromimage(b);
// 插值算法的质量
g.interpolationmode = interpolationmode.default;
g.drawimage(srcimage, new rectangle(0, 0, neww, newh), new rectangle(0, 0, srcimage.width, srcimage.height), graphicsunit.pixel);
g.dispose();
return b;
}
catch (exception)
{
return null;
}
}
2.按照指定像素大小截图
view code
/// <summary>
/// 按照指定大小缩放图片
/// </summary>
/// <param name="srcimage"></param>
/// <param name="iwidth"></param>
/// <param name="iheight"></param>
/// <returns></returns>
public static bitmap sizeimage(image srcimage, int iwidth, int iheight)
{
try
{
// 要保存到的图片
bitmap b = new bitmap(iwidth, iheight);
graphics g = graphics.fromimage(b);
// 插值算法的质量
g.interpolationmode = interpolationmode.highqualitybicubic;
g.drawimage(srcimage, new rectangle(0, 0, iwidth, iheight), new rectangle(0, 0, srcimage.width, srcimage.height), graphicsunit.pixel);
g.dispose();
return b;
}
catch (exception)
{
return null;
}
}
3.按照指定像素大小截图(但为了保证图片的原始比例,将对图片从中心进行截取,达到图片不被拉伸的效果)
view code
/// <summary>
/// 按照指定大小缩放图片,但是为了保证图片宽高比自动截取
/// </summary>
/// <param name="srcimage"></param>
/// <param name="iwidth"></param>
/// <param name="iheight"></param>
/// <returns></returns>
public static bitmap sizeimagewitholdpercent(image srcimage, int iwidth, int iheight)
{
try
{
// 要截取图片的宽度(临时图片)
int neww = srcimage.width;
// 要截取图片的高度(临时图片)
int newh = srcimage.height;
// 截取开始横坐标(临时图片)
int newx = 0;
// 截取开始纵坐标(临时图片)
int newy = 0;
// 截取比例(临时图片)
double whpercent = 1;
whpercent = ((double)iwidth / (double)iheight) * ((double)srcimage.height / (double)srcimage.width);
if (whpercent > 1)
{
// 当前图片宽度对于要截取比例过大时
neww = int.parse(math.round(srcimage.width / whpercent).tostring());
}
else if (whpercent < 1)
{
// 当前图片高度对于要截取比例过大时
newh = int.parse(math.round(srcimage.height * whpercent).tostring());
}
if (neww != srcimage.width)
{
// 宽度有变化时,调整开始截取的横坐标
newx = math.abs(int.parse(math.round(((double)srcimage.width - neww) / 2).tostring()));
}
else if (newh == srcimage.height)
{
// 高度有变化时,调整开始截取的纵坐标
newy = math.abs(int.parse(math.round(((double)srcimage.height - (double)newh) / 2).tostring()));
}
// 取得符合比例的临时文件
bitmap cutedimage = cutimage(srcimage, newx, newy, neww, newh);
// 保存到的文件
bitmap b = new bitmap(iwidth, iheight);
graphics g = graphics.fromimage(b);
// 插值算法的质量
g.interpolationmode = interpolationmode.default;
g.drawimage(cutedimage, new rectangle(0, 0, iwidth, iheight), new rectangle(0, 0, cutedimage.width, cutedimage.height), graphicsunit.pixel);
g.dispose();
return b;
}
catch (exception)
{
return null;
}
}
4.jpeg图片质量压缩,压缩的比例参数在1-100之间。(适量的压缩对于肉眼来说没有什么明显的区别,但是能够大大的减小图片的占用大小)
view code
/// <summary>
/// jpeg图片压缩
/// </summary>
/// <param name="sfile"></param>
/// <param name="outpath"></param>
/// <param name="flag"></param>
/// <returns></returns>
public static bool getpicthumbnail(string sfile, string outpath, int flag)
{
system.drawing.image isource = system.drawing.image.fromfile(sfile);
imageformat tformat = isource.rawformat;
//以下代码为保存图片时,设置压缩质量
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)
{
isource.save(outpath, jpegiciinfo, ep);//dfile是压缩后的新路径
}
else
{
isource.save(outpath, tformat);
}
return true;
}
catch
{
return false;
}
finally
{
isource.dispose();
isource.dispose();
}
}
ps:之上用的cutimage方法的补充
view code
/// <summary>
/// 剪裁 -- 用gdi+
/// </summary>
/// <param name="b">原始bitmap</param>
/// <param name="startx">开始坐标x</param>
/// <param name="starty">开始坐标y</param>
/// <param name="iwidth">宽度</param>
/// <param name="iheight">高度</param>
/// <returns>剪裁后的bitmap</returns>
public static bitmap cutimage(image b, int startx, int starty, int iwidth, int iheight)
{
if (b == null)
{
return null;
}
int w = b.width;
int h = b.height;
if (startx >= w || starty >= h)
{
// 开始截取坐标过大时,结束处理
return null;
}
if (startx + iwidth > w)
{
// 宽度过大时只截取到最大大小
iwidth = w - startx;
}
if (starty + iheight > h)
{
// 高度过大时只截取到最大大小
iheight = h - starty;
}
try
{
bitmap bmpout = new bitmap(iwidth, iheight);
graphics g = graphics.fromimage(bmpout);
g.drawimage(b, new rectangle(0, 0, iwidth, iheight), new rectangle(startx, starty, iwidth, iheight), graphicsunit.pixel);
g.dispose();
return bmpout;
}
catch
{
return null;
}
}
再次记录下截取的代码,虽然简单,如果重写还是需要花费时间。
为了娱乐写了个截取图片和压缩图片你的小工具
1.按照百分比截图
复制代码 代码如下:
view code
/// <summary>
/// 按照比例缩小图片
/// </summary>
/// <param name="srcimage">要缩小的图片</param>
/// <param name="percent">缩小比例</param>
/// <returns>缩小后的结果</returns>
public static bitmap percentimage(image srcimage, double percent)
{
// 缩小后的高度
int newh = int.parse(math.round(srcimage.height * percent).tostring());
// 缩小后的宽度
int neww = int.parse(math.round(srcimage.width * percent).tostring());
try
{
// 要保存到的图片
bitmap b = new bitmap(neww, newh);
graphics g = graphics.fromimage(b);
// 插值算法的质量
g.interpolationmode = interpolationmode.default;
g.drawimage(srcimage, new rectangle(0, 0, neww, newh), new rectangle(0, 0, srcimage.width, srcimage.height), graphicsunit.pixel);
g.dispose();
return b;
}
catch (exception)
{
return null;
}
}
2.按照指定像素大小截图
复制代码 代码如下:
view code
/// <summary>
/// 按照指定大小缩放图片
/// </summary>
/// <param name="srcimage"></param>
/// <param name="iwidth"></param>
/// <param name="iheight"></param>
/// <returns></returns>
public static bitmap sizeimage(image srcimage, int iwidth, int iheight)
{
try
{
// 要保存到的图片
bitmap b = new bitmap(iwidth, iheight);
graphics g = graphics.fromimage(b);
// 插值算法的质量
g.interpolationmode = interpolationmode.highqualitybicubic;
g.drawimage(srcimage, new rectangle(0, 0, iwidth, iheight), new rectangle(0, 0, srcimage.width, srcimage.height), graphicsunit.pixel);
g.dispose();
return b;
}
catch (exception)
{
return null;
}
}
3.按照指定像素大小截图(但为了保证图片的原始比例,将对图片从中心进行截取,达到图片不被拉伸的效果)
复制代码 代码如下:
view code
/// <summary>
/// 按照指定大小缩放图片,但是为了保证图片宽高比自动截取
/// </summary>
/// <param name="srcimage"></param>
/// <param name="iwidth"></param>
/// <param name="iheight"></param>
/// <returns></returns>
public static bitmap sizeimagewitholdpercent(image srcimage, int iwidth, int iheight)
{
try
{
// 要截取图片的宽度(临时图片)
int neww = srcimage.width;
// 要截取图片的高度(临时图片)
int newh = srcimage.height;
// 截取开始横坐标(临时图片)
int newx = 0;
// 截取开始纵坐标(临时图片)
int newy = 0;
// 截取比例(临时图片)
double whpercent = 1;
whpercent = ((double)iwidth / (double)iheight) * ((double)srcimage.height / (double)srcimage.width);
if (whpercent > 1)
{
// 当前图片宽度对于要截取比例过大时
neww = int.parse(math.round(srcimage.width / whpercent).tostring());
}
else if (whpercent < 1)
{
// 当前图片高度对于要截取比例过大时
newh = int.parse(math.round(srcimage.height * whpercent).tostring());
}
if (neww != srcimage.width)
{
// 宽度有变化时,调整开始截取的横坐标
newx = math.abs(int.parse(math.round(((double)srcimage.width - neww) / 2).tostring()));
}
else if (newh == srcimage.height)
{
// 高度有变化时,调整开始截取的纵坐标
newy = math.abs(int.parse(math.round(((double)srcimage.height - (double)newh) / 2).tostring()));
}
// 取得符合比例的临时文件
bitmap cutedimage = cutimage(srcimage, newx, newy, neww, newh);
// 保存到的文件
bitmap b = new bitmap(iwidth, iheight);
graphics g = graphics.fromimage(b);
// 插值算法的质量
g.interpolationmode = interpolationmode.default;
g.drawimage(cutedimage, new rectangle(0, 0, iwidth, iheight), new rectangle(0, 0, cutedimage.width, cutedimage.height), graphicsunit.pixel);
g.dispose();
return b;
}
catch (exception)
{
return null;
}
}
4.jpeg图片质量压缩,压缩的比例参数在1-100之间。(适量的压缩对于肉眼来说没有什么明显的区别,但是能够大大的减小图片的占用大小)
复制代码 代码如下:
view code
/// <summary>
/// jpeg图片压缩
/// </summary>
/// <param name="sfile"></param>
/// <param name="outpath"></param>
/// <param name="flag"></param>
/// <returns></returns>
public static bool getpicthumbnail(string sfile, string outpath, int flag)
{
system.drawing.image isource = system.drawing.image.fromfile(sfile);
imageformat tformat = isource.rawformat;
//以下代码为保存图片时,设置压缩质量
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)
{
isource.save(outpath, jpegiciinfo, ep);//dfile是压缩后的新路径
}
else
{
isource.save(outpath, tformat);
}
return true;
}
catch
{
return false;
}
finally
{
isource.dispose();
isource.dispose();
}
}
ps:之上用的cutimage方法的补充
复制代码 代码如下:
view code
/// <summary>
/// 剪裁 -- 用gdi+
/// </summary>
/// <param name="b">原始bitmap</param>
/// <param name="startx">开始坐标x</param>
/// <param name="starty">开始坐标y</param>
/// <param name="iwidth">宽度</param>
/// <param name="iheight">高度</param>
/// <returns>剪裁后的bitmap</returns>
public static bitmap cutimage(image b, int startx, int starty, int iwidth, int iheight)
{
if (b == null)
{
return null;
}
int w = b.width;
int h = b.height;
if (startx >= w || starty >= h)
{
// 开始截取坐标过大时,结束处理
return null;
}
if (startx + iwidth > w)
{
// 宽度过大时只截取到最大大小
iwidth = w - startx;
}
if (starty + iheight > h)
{
// 高度过大时只截取到最大大小
iheight = h - starty;
}
try
{
bitmap bmpout = new bitmap(iwidth, iheight);
graphics g = graphics.fromimage(bmpout);
g.drawimage(b, new rectangle(0, 0, iwidth, iheight), new rectangle(startx, starty, iwidth, iheight), graphicsunit.pixel);
g.dispose();
return bmpout;
}
catch
{
return null;
}
}
再次记录下截取的代码,虽然简单,如果重写还是需要花费时间。