图片切割系统

简介:

上一阵子做过一个图片切割效果,得到很多人关注。其中有很多人向我询问如何做一个真正的图片切割(裁剪),这里需要声明一下:
首先js是不能操作客户端文件的(除非特殊情况),所以图片的切割必须在后台处理,对于客户端的图片可以先上传再切割或者把图片和切割参数一起传递到服务器再处理(上传文件不在本次讨论范围,请自行修改);
还有是通过客户端传递的参数来处理图片,确实能得到展示图或预览图的效果(这是针对有些提出在后台处理的图片得不到预览图的效果来说的),下面会举例说明如何生成展示图那样的图片。

程序说明
【客户端部分】
客户端部分详细请参考图片切割效果(建议没有看过的先看那里的例子),这里说说要传递到后台的参数,建议用GetPos获取部分参数:

var  p  =  ic.Url, o  =  ic.GetPos();
=  o.Left,
=  o.Top,
=  o.Width,
=  o.Height,
pw 
=  ic._layBase.width,
ph 
=  ic._layBase.height;

其中,ic.Url是图片地址:ic.Url,o.Left是水平切割,o.Top是垂直切割点,o.Width是切割宽度,o.Height是切割高度,ic._layBase.width是图片宽度,ic._layBase.height是图片高度。
可以这样传递这些参数:

$( " imgCreat " ).src  =   " ImgCropper.ashx?p= "   +  p  +   " &x= "   +  x  +   " &y= "   +  y  +   " &w= "   +  w  +   " &h= "   +  h  +   " &pw= "   +  pw  +   " &ph= "   +  ph  +   " & "   +  Math.random();

其中图片地址、图片宽度、图片高度如果是预先设定好的话就可以不传递了。
【后台部分】
后台主要是进行图片的处理和输出。
【图片切割】
在后台获取前台传递的参数:

string Pic = Convert.ToString(context.Request["p"]);
int PointX = Convert.ToInt32(context.Request["x"]);
int PointY = Convert.ToInt32(context.Request["y"]);
int CutWidth = Convert.ToInt32(context.Request["w"]);
int CutHeight = Convert.ToInt32(context.Request["h"]);
int PicWidth = Convert.ToInt32(context.Request["pw"]);
int PicHeight = Convert.ToInt32(context.Request["ph"]);

然后就用这些参数对图片进行切割了,先说说切割的原理,主要分两部:切割和缩放。
切割和缩放的程序关键在这里:

gbmPhoto.DrawImage(imgPhoto,  new  Rectangle( 0 0 , CutWidth, CutHeight), PointX  *  imgPhoto.Width  /  PicWidth, PointY  *  imgPhoto.Height  /  PicHeight, CutWidth  *  imgPhoto.Width  /  PicWidth, CutHeight  *  imgPhoto.Height  /  PicHeight, GraphicsUnit.Pixel);

首先是在原图切割出需要的部分。切割需要的参数是PointX、PointY、CutWidth、CutHeight,因为在客户端的程序中是可以缩放原图来进行切割的,所以要在在切割原图时需要先按比例缩放这些参数,还要注意PointX和CutWidth需要水平方向的比例,PointY和CutHeight需要垂直方向的比例。例如(其中imgPhoto是原图):
水平切割点:PointX * imgPhoto.Width / PicWidth;
切割宽度:CutWidth * imgPhoto.Width / PicWidth;
垂直切割点:PointY * imgPhoto.Height / PicHeight;
切割高度:CutHeight * imgPhoto.Height / PicHeight。
用这些参数就可以对原图进行切割了。
然后是缩放原图。可以想象,当切割好原图后,只要把图宽高缩放到CutWidth和CutHeight就可以得到跟展示图一样的图片了:

new  Rectangle( 0 0 , CutWidth, CutHeight), 

下面是处理图片的程序:

    public MemoryStream ResetImg(string ImgFile, int PicWidth, int PicHeight, int PointX, int PointY, int CutWidth, int CutHeight)
    {
        Image imgPhoto 
= Image.FromFile(ImgFile);
        Bitmap bmPhoto 
= new Bitmap(CutWidth, CutHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

        Graphics gbmPhoto 
= Graphics.FromImage(bmPhoto);
        gbmPhoto.DrawImage(imgPhoto, 
new Rectangle(00, CutWidth, CutHeight), PointX * imgPhoto.Width / PicWidth, PointY * imgPhoto.Height / PicHeight, CutWidth * imgPhoto.Width / PicWidth, CutHeight * imgPhoto.Height / PicHeight, GraphicsUnit.Pixel);

        MemoryStream ms2 
= new MemoryStream();
        bmPhoto.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);

        imgPhoto.Dispose();
        gbmPhoto.Dispose();
        bmPhoto.Dispose();

        
return ms2;
    }

当然对于不同的需求可能要生成的效果也不一样,但只要能灵活运用对于一般的需求基本都能实现了。
如果需要保存图片到服务器,那么可以用下面的方法保存图片:

bmPhoto.Save(文件物理路径, System.Drawing.Imaging.ImageFormat.Jpeg);

【IHttpHandler】
程序通过ashx文件用IHttpHandler发送切割生成的图片,参考使用.ashx文件处理IHttpHandler实现发送文本及二进制数据的方法
“利用.ashx文件是一个更好的方法,这个文件类似于.aspx文件,可以通过它来调用HttpHandler类,从而免去了普通.aspx页面的控件解析以及页面处理的过程。这个文件特别适合于生成动态图片,生成动态文本等内容。”
最后设置数据输出类型context.Response.ContentType,并使用context.Response.OutputStream向客户端输出图片数据:

context.Response.ContentType  =   " image/jpeg " ;
ResetImg(System.Web.HttpContext.Current.Server.MapPath(Pic), PicWidth, PicHeight, PointX, PointY, CutWidth, CutHeight).WriteTo(context.Response.OutputStream);

这个输出数据的方法适合用在不需要回发的数据输出中,例如ajax、动态图片等,关于这方面更详细的内容请看IHttpHandler接口
下面是完整服务器端代码:

<%@ WebHandler Language="c#" Class="ImgCropper_WebHandler" Debug="true" %>

using System;
using System.Web;
using System.Drawing;
using System.IO;

public class ImgCropper_WebHandler : IHttpHandler
{
    
public void ProcessRequest(HttpContext context)
    {
        
string Pic = Convert.ToString(context.Request["p"]);
        
int PointX = Convert.ToInt32(context.Request["x"]);
        
int PointY = Convert.ToInt32(context.Request["y"]);
        
int CutWidth = Convert.ToInt32(context.Request["w"]);
        
int CutHeight = Convert.ToInt32(context.Request["h"]);
        
int PicWidth = Convert.ToInt32(context.Request["pw"]);
        
int PicHeight = Convert.ToInt32(context.Request["ph"]);

        context.Response.ContentType 
= "image/jpeg";
        ResetImg(System.Web.HttpContext.Current.Server.MapPath(Pic), PicWidth, PicHeight, PointX, PointY, CutWidth, CutHeight).WriteTo(context.Response.OutputStream);
    }
    
    
public MemoryStream ResetImg(string ImgFile, int PicWidth, int PicHeight, int PointX, int PointY, int CutWidth, int CutHeight)
    {
        Image imgPhoto 
= Image.FromFile(ImgFile);
        Bitmap bmPhoto 
= new Bitmap(CutWidth, CutHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

        Graphics gbmPhoto 
= Graphics.FromImage(bmPhoto);
        gbmPhoto.DrawImage(imgPhoto, 
new Rectangle(00, CutWidth, CutHeight), PointX * imgPhoto.Width / PicWidth, PointY * imgPhoto.Height / PicHeight, CutWidth * imgPhoto.Width / PicWidth, CutHeight * imgPhoto.Height / PicHeight, GraphicsUnit.Pixel);

        MemoryStream ms2 
= new MemoryStream();
        bmPhoto.Save(ms2, System.Drawing.Imaging.ImageFormat.Jpeg);

        imgPhoto.Dispose();
        gbmPhoto.Dispose();
        bmPhoto.Dispose();

        
return ms2;
    }


    
public bool IsReusable
    {
        
get
        {
            
return false;
        }
    }
}

各位有什么建议或意见欢迎留言讨论,由于涉及后台操作,请下载完整实例测试。
下载完整测试实例(.net版本) 
下载完整测试实例(asp版本) 
ps:实例中没有加入图片,测试时请自己插入一张图片(默认是1.jpg)。 
ps2:应要求把asp版本加上了,但需要支持aspjpeg组件。

本文转自博客园cloudgamer的博客,原文链接:图片切割系统,如需转载请自行联系原博主。

相关文章
|
5月前
|
机器学习/深度学习 算法 数据安全/隐私保护
使用程序去除图片水印的一些思路
使用程序去除图片水印的一些思路
|
Ubuntu 定位技术 API
python 通过图片(原图)精确获取图片拍摄的位置,时间,设备等信息
python 通过图片(原图)精确获取图片拍摄的位置,时间,设备等信息
python 通过图片(原图)精确获取图片拍摄的位置,时间,设备等信息
|
4月前
|
存储 Python
python实现图片与视频转换:将视频保存为图片,将批量图片保存为视频
python实现图片与视频转换:将视频保存为图片,将批量图片保存为视频
|
9天前
|
计算机视觉
两种切割裁剪,切割图片的方法
两种切割裁剪,切割图片的方法
|
3月前
|
编解码 定位技术
【工具分享】如何批量获取图片详细信息,如何把图片的属性信息包括文件路径、文件名、面积尺寸、创建日期、修改日期、水平垂直分辨率、文件大小等图片信息批量提取exel表格中
本文介绍了如何批量提取图片的属性数据到Excel,包括文件名、尺寸、面积、分辨率、GPS信息、创建和修改日期。适合需要处理大量图片信息的工作场景。支持批量导入图片,一键提取各项信息,并能直接导出为表格。
|
4月前
|
存储 编解码 API
如何通过编程获取桌面分辨率、操作像素点颜色、保存位图和JPG格式图片,以及图片数据的处理和存储方式
如何通过编程获取桌面分辨率、操作像素点颜色、保存位图和JPG格式图片,以及图片数据的处理和存储方式
58 0
【图片操作】混合图片
混合图片的方式有很多种,我们先来看看如何通过混合图片的通道来实现图片混合。
148 0
|
计算机视觉 Python
训练集制作:以指定帧间隔截取视频为图片,并保存指定路径及名称
训练集制作:以指定帧间隔截取视频为图片,并保存指定路径及名称
训练集制作:以指定帧间隔截取视频为图片,并保存指定路径及名称
Halcon打开图片:单个图片以及遍历读取文件夹里的所有图片
Halcon打开图片:单个图片以及遍历读取文件夹里的所有图片
962 0