【小5聊】情人节送给爱人的心形创意相册

目录

【实现效果】

【开篇小叙】

【开发描述】

【简单设计】

【前端实现简述】

【后端实现简述】

【前端完整代码】

【后端完整代码】


【实现效果】

【开篇小叙】

新年之际,祝大家在新的一年里牛年大吉、家庭美满、万事顺利、生意兴隆、职位晋升、奖金多多。在情人节里,祝单身的小伙伴们必定找到心中所爱,祝已有佳人的小伙伴们更加幸福甜蜜。所以,小5也要在情人节送给爱人一份小小礼物,将和爱人的图片一键生成心形相册作为一件小惊喜,通过我们所学的技术也能创造点小浪漫,加油小伙伴们!

【开发描述】

  • 开发框架:.Net Framework 4.6.1
  • 开发语言:C#
  • 前端框架:css+div布局,jquery+jquery.form

【简单设计】

简单的在Excel文档里大概设计心形相册草稿,默认格式如下

宽为11个单元格子,高为10个单元格子。

分两部分,心形外边单元格和心形内部单元格,每一个单元格为一张图片,图片可重复,如果是多张图片,则随机显示。至少两张图片,选择第一张图片作为单元格外边,其他图片则随机在心形内部单元格随机显示。

目的是可以将和爱人的合照等图片生成一张心形相册,作为一个创意相册保存起来也是不错的一件小惊喜!

【前端实现简述】

主要实现能够上传图片前进行预览,以及点击一键生成心形相册按钮时,能够调用后台接口生成心形相册图片

1、jquery引用,用于上传图片按钮的操作,此处可以单张图片选择或者多张图片选择预览显示

2、form引用,用于form表单提交图片,点击下载form表单js

【后端实现简述】

  • 获取图片

将前端传递过来的所有图片放到List泛型集合里,必须大于两张图片才能生成心形相册,当然,越多图片效果越好,最多64张图片。

尽量将图片设置统一大小或者高宽度差别不大的一批图片,这样生成会显示比较全,代码里也进行了逻辑处理,确保了520px正方形里能够填完图片,在不变形的情况下

  • 单元格和背景底图

设置单元格大小,高度=520px,宽度=520px,默认白色背景,因此,整个底图的高度=10*520=5200,宽度=11*520=5720

  • 叠加图片

这里的叠加逻辑是,先从左上角开始,先行后列进行定位,根据excel设计好的图案给对应坐标的单元格叠加上图片即可

外边单元格子图片逻辑

第一行的第4列、第8列为一个外边图片单元格
第二行的第3、5、7、9列为一个外边图片单元格
第三行的第2、6、10列为一个外边图片单元格
第四、五行的第1、11列为一个外边图片单元格
第六行的第2、10列为一个外边图片单元格
第七行的第3、9列为一个外边图片单元格
第八行的第4、8列为一个外边图片单元格
第九行的第5、7列为一个外边图片单元格
第十行的第6列为一个外边图片单元格

  • 温馨提示

解决上传太多图片文件太大的问题

由于C#对于传统的input-file默认能接收4M大小的文件图片,所以在上传60多张 图片时,肯定超过了4M,需要通过web.config配置修改限制

方式一 :设置请求大小,maxRequestLength,以及线程数

<system.web>
  <httpRuntime targetFramework="4.5.2" executionTimeout="90" maxRequestLength="2097151" useFullyQualifiedRedirectUrl="false" minFreeThreads="8" minLocalRequestFreeThreads="4" appRequestQueueLimit="100"/>
  <compilation debug="true" targetFramework="4.6.1" />
</system.web>

方式二:设置最大允许内容大小,maxAllowedContentLength

<system.webServer>
  <security>
    <requestFiltering>
      <requestLimits maxAllowedContentLength="2072576000"/>
    </requestFiltering>
  </security>
</system.webServer>

 

【前端完整代码】


<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
<style type="text/css">
    html, body {
        margin: 0;
        padding: 0;
        background: #f9f9f9;
        font-size: 13px;
    }

    .clear {
        *zoom: 1;
    }

        .clear:after {
            content: '';
            display: table;
            clear: both;
        }
</style>

<div>
    <form id="imageForm" style="display:block;">
        <div class="clear" style="margin:10px 0px;width:auto;height:35px;line-height:35px;">
            <div class="btnGet" style="float:left;width:100%;height:100%;background:#0aadff;color:#fff;text-align:center;cursor:pointer;">
                <span style="font-size:1.3rem;">一键生成心形相册</span>
            </div>
        </div>

        <div class="fileList" style="margin-top:10px;">

        </div>

        <div class="" style="margin-top:10px;width:100%;text-align:center;color:#555;">
            <div class="preImage clear"></div>
            <div id="btn" style="margin:0 auto;margin-top:10px;width:80%;height:50px;line-height:50px;color:#888;text-align:center;position:relative;">
                <div style="border:1px dashed #ccc;">
                    <span style="font-size:30px;">+</span>
                    <input class="image-file" name="file" type="file" multiple="multiple" style="opacity:0;width:100%;height:100%;position:absolute;top:0px;left:0px;" />
                </div>
            </div>
        </div>
        <div class="gifImage" style="margin-top:10px;width:100%;text-align:center;color:#555;"></div>
    </form>
</div>

<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="/jQuery/jquery.form.js"></script>
<script type="text/javascript">

    (function () {

        var param = {
            getImageColorUrl: 'http://localhost:5852/Image/LoveImage',
            x: 0,
            y: 0,
            width: 0,
            height: 0,
            imgLength: 0,
            getImageColor: function () {

                if ($(".image-file").val() == '') {

                    alert('请上传图片!');
                    return;
                }

                var data = { x: param.x, y: param.y, width: param.width, height: param.height };

                $(".btnGet span").html("图片图生成中...");

                $("#imageForm").ajaxSubmit({
                    url: param.getImageColorUrl,
                    data: data,
                    dataType: "json",
                    type: 'post',
                    success: function (d) {

                        param.flag = 0;

                        $(".btnGet span").html("一键生成心形相册");

                        if (d.c == 200) {

                            $(".gifImage").html('<img src="' + d.d + '" style="width:80%;margin:0 auto;" />');
                        }
                        else {

                            alert(d.m);
                        }
                    },
                    error: function () {

                        $(".btnGet span").html("一键生成心形相册");

                        param.flag = 0;
                    }
                });
            },
            imageColor: function () {

                $(".btnGet").click(function () {

                    if (param.imgLength < 2) {

                        alert('请上传两张以及以上的图片!');
                        return;
                    }

                    param.width = 0;
                    param.getImageColor();
                });
            },
            imageScan: function () { //图片预览

                param.previewImageMore({
                    idClass: ".image-file",
                    success: function (base64) {

                        param.imgLength = $(".image-file").length;

                        var html = '';

                        html += '<div style="float:left;width:25%;text-align:center;"><img class="item" src="' + base64 + '" style="width:90%;" /></div>'

                        $(".preImage").append(html);

                        $(".image-file").eq(length - 1).css("top", "-1000px");
                        $("#btn").append('<input class="image-file" name="file" type="file" multiple="multiple" style="opacity:0;width:100%;position:absolute;top:0px;left:0px;" />');
                    }
                });
            },
            previewImageMore: function (param) {

                $("body").off("change", param.idClass);
                $("body").on("change", param.idClass, function () {
                    var that = this;
                    if (typeof FileReader == 'undefined') alert("浏览器不支持FileReader接口");

                    var file = that.files; //选择图片,马上预览
                    for (var i = 0; i < file.length; i++) {
                        var _file = file[i];

                        var reader = new FileReader();
                        reader.readAsDataURL(_file);

                        reader.onload = function (e) {
                            
                            param.success(e.target.result); //base64
                        }
                    }
                });
            }
        };

        $(function () {

            param.imageColor();
            param.imageScan();
        });

    })();

</script>

【后端完整代码】

#region 心形相册
public JsonResult LoveImage(int maxSize = 520)
{
    try
    {
        #region 获取前端图片
        HttpRequestBase Request = new HttpRequestWrapper(System.Web.HttpContext.Current.Request);

        //获取web端form表单提交过来的图片
        HttpFileCollectionBase file = Request.Files; //Request.Files和Request.Files["file"],加个中括号表示具体的一个了
        if (file == null)
        {
            return Json(r);
        }

        //有效图片判断
        List<Image> imageList = new List<Image>();
        int num = 0;
        foreach (string key in file.AllKeys)
        {
            HttpPostedFileBase item = file[num];
            num++;

            //保证图片最小高宽度为520px
            //取中间图片
            int newWidth = 0;
            int newHeight = 0;
            Image image = Image.FromStream(item.InputStream);
            if (image.Width > image.Height)
            {
                newHeight = maxSize;
                newWidth = (image.Width * newHeight) / image.Height;
            }
            else
            {
                newWidth = maxSize;
                newHeight = (image.Height * newWidth) / image.Width;
            }

            image = GetNewImageByWidthOrHeight(image, newWidth, newHeight);

            imageList.Add(image);
        }
        #endregion

        #region 创建底图 - 白色背景
        int widthCount = 11;
        int heightCount = 10;
        int widthBg = widthCount * maxSize;
        int heightBg = heightCount * maxSize;
        Image backgroundImage = new Bitmap(widthBg, heightBg);

        using (Graphics graphics = Graphics.FromImage(backgroundImage)) //定义一个绘图对象
        {
            Color color_a = ColorTranslator.FromHtml("#fff");
            graphics.FillRectangle(new SolidBrush(color_a), new Rectangle(0, 0, widthBg, heightBg)); //给图片填充颜色
        }
        #endregion

        //叠加图片 - 根据坐标
        for(int y = 0; y < 10; y++)
        {
            for (int x = 0; x < 11; x++)
            {
                //#region 方式一
                从左上角到右下角的方式叠加单元格子
                第一行的第4列、第8列为一个外边图片单元格
                第二行的第3、5、7、9列为一个外边图片单元格
                第三行的第2、6、10列为一个外边图片单元格
                第四、五行的第1、11列为一个外边图片单元格
                第六行的第2、10列为一个外边图片单元格
                第七行的第3、9列为一个外边图片单元格
                第八行的第4、8列为一个外边图片单元格
                第九行的第5、7列为一个外边图片单元格
                第十行的第6列为一个外边图片单元格
                //if (y == 0 && x == 3 || y == 0 && x == 7 ||
                //    y == 1 && x == 2 || y == 1 && x == 4 || y == 1 && x == 6 || y == 1 && x == 8 ||
                //    y == 2 && x == 1 || y == 2 && x == 5 || y == 2 && x == 9 ||
                //    y == 3 && x == 0 || y == 3 && x == 10 ||
                //    y == 4 && x == 0 || y == 4 && x == 10 ||
                //    y == 5 && x == 1 || y == 5 && x == 9 ||
                //    y == 6 && x == 2 || y == 6 && x == 8 ||
                //    y == 7 && x == 3 || y == 7 && x == 7 ||
                //    y == 8 && x == 4 || y == 8 && x == 6 ||
                //    y == 9 && x == 5)
                //{
                //    Image image = imageList[1];
                //    image = ImageHelper.CutImage(image, 0, 0, maxSize, maxSize);
                //    using (Graphics graphics = Graphics.FromImage(backgroundImage))
                //    {
                //        int imageInBackgroundImage_x = x * maxSize;
                //        int imageInBackgroundImage_y = y * maxSize;//第一行
                //        Rectangle _r = new Rectangle(imageInBackgroundImage_x, imageInBackgroundImage_y, image.Width, image.Height); //叠图相对于底图的坐标

                //        int imageSelf_x = 0; //相对叠图自己的坐标系x轴,假设宽度为50,那么设置x=50,那么相对于自己的体系,就超出了自己的宽度,就看不见了
                //        int imageSelf_y = 0; //相对叠图自己的坐标系y轴
                //        graphics.DrawImage(image, _r, imageSelf_x, imageSelf_y, image.Width, image.Height, GraphicsUnit.Pixel);
                //    }
                //}
                //#endregion

                //#region 方式二
                从左上角到右下角的方式叠加单元格子
                第一行的第4列、第8列为一个外边图片单元格
                第二行的第3、5、7、9列为一个外边图片单元格
                第三行的第2、6、10列为一个外边图片单元格
                第四、五行的第1、11列为一个外边图片单元格
                第六行的第2、10列为一个外边图片单元格
                第七行的第3、9列为一个外边图片单元格
                第八行的第4、8列为一个外边图片单元格
                第九行的第5、7列为一个外边图片单元格
                第十行的第6列为一个外边图片单元格
                //int randomNum = RandomHelper.GetNumByValue(0, imageList.Count);
                //if (y == 0 && x == 3 || y == 0 && x == 7 ||
                //    y == 1 && (x >= 2 && x <= 4 || x >= 6 && x <= 8) ||
                //    y == 2 && (x >= 1 && x <= 9) ||
                //    y == 3 && (x >= 0 && x <= 10) ||
                //    y == 4 && (x >= 0 && x <= 10) ||
                //    y == 5 && (x >= 1 && x <= 9) ||
                //    y == 6 && (x >= 2 && x <= 8) ||
                //    y == 7 && (x >= 3 && x <= 7) ||
                //    y == 8 && (x >= 4 && x <= 6) ||
                //    y == 9 && (x == 5))
                //{
                //    Image image = imageList[randomNum];
                //    image = ImageHelper.CutImage(image, 0, 0, maxSize, maxSize);
                //    using (Graphics graphics = Graphics.FromImage(backgroundImage))
                //    {
                //        int imageInBackgroundImage_x = x * maxSize;
                //        int imageInBackgroundImage_y = y * maxSize;//第一行
                //        Rectangle _r = new Rectangle(imageInBackgroundImage_x, imageInBackgroundImage_y, image.Width, image.Height); //叠图相对于底图的坐标

                //        int imageSelf_x = 0; //相对叠图自己的坐标系x轴,假设宽度为50,那么设置x=50,那么相对于自己的体系,就超出了自己的宽度,就看不见了
                //        int imageSelf_y = 0; //相对叠图自己的坐标系y轴
                //        graphics.DrawImage(image, _r, imageSelf_x, imageSelf_y, image.Width, image.Height, GraphicsUnit.Pixel);
                //    }
                //}
                //#endregion

                #region 方式三
                if (y == 0 && x == 3 || y == 0 && x == 7 ||
                    y == 1 && x == 2 || y == 1 && x == 4 || y == 1 && x == 6 || y == 1 && x == 8 ||
                    y == 2 && x == 1 || y == 2 && x == 5 || y == 2 && x == 9 ||
                    y == 3 && x == 0 || y == 3 && x == 10 ||
                    y == 4 && x == 0 || y == 4 && x == 10 ||
                    y == 5 && x == 1 || y == 5 && x == 9 ||
                    y == 6 && x == 2 || y == 6 && x == 8 ||
                    y == 7 && x == 3 || y == 7 && x == 7 ||
                    y == 8 && x == 4 || y == 8 && x == 6 ||
                    y == 9 && x == 5)
                {
                    Image image = imageList[0];
                    image = ImageHelper.CutImage(image, 0, 0, maxSize, maxSize);
                    using (Graphics graphics = Graphics.FromImage(backgroundImage))
                    {
                        int imageInBackgroundImage_x = x * maxSize;
                        int imageInBackgroundImage_y = y * maxSize;//第一行
                        Rectangle _r = new Rectangle(imageInBackgroundImage_x, imageInBackgroundImage_y, image.Width, image.Height); //叠图相对于底图的坐标

                        int imageSelf_x = 0; //相对叠图自己的坐标系x轴,假设宽度为50,那么设置x=50,那么相对于自己的体系,就超出了自己的宽度,就看不见了
                        int imageSelf_y = 0; //相对叠图自己的坐标系y轴
                        graphics.DrawImage(image, _r, imageSelf_x, imageSelf_y, image.Width, image.Height, GraphicsUnit.Pixel);
                    }
                }
                else
                {
                    int randomNum = RandomHelper.GetNumByValue(1, imageList.Count);
                    if (y == 1 && (x == 3 || x >= 6 && x == 7) ||
                        y == 2 && (x >= 2 && x <= 4|| x >= 6 && x <= 8) ||
                        y == 3 && (x >= 1 && x <= 9) ||
                        y == 4 && (x >= 1 && x <= 9) ||
                        y == 5 && (x >= 2 && x <= 8) ||
                        y == 6 && (x >= 3 && x <= 7) ||
                        y == 7 && (x >= 4 && x <=6) ||
                        y == 8 && (x == 5))
                    {
                        Image image = imageList[randomNum];
                        image = ImageHelper.CutImage(image, 0, 0, maxSize, maxSize);
                        using (Graphics graphics = Graphics.FromImage(backgroundImage))
                        {
                            int imageInBackgroundImage_x = x * maxSize;
                            int imageInBackgroundImage_y = y * maxSize;//第一行
                            Rectangle _r = new Rectangle(imageInBackgroundImage_x, imageInBackgroundImage_y, image.Width, image.Height); //叠图相对于底图的坐标

                            int imageSelf_x = 0; //相对叠图自己的坐标系x轴,假设宽度为50,那么设置x=50,那么相对于自己的体系,就超出了自己的宽度,就看不见了
                            int imageSelf_y = 0; //相对叠图自己的坐标系y轴
                            graphics.DrawImage(image, _r, imageSelf_x, imageSelf_y, image.Width, image.Height, GraphicsUnit.Pixel);
                        }
                    }
                }
                #endregion
            }
        }

        //保存图片
        GetPathModel pathModel = CommonHelper.GetPathEx("LoveImage");
        backgroundImage.Save(pathModel.all);
    }
    catch (Exception ex)
    {
        LogHelper.Error(ex);
    }

    return Json(r);
}
#endregion

#region 图片的放大与缩小
public static Bitmap GetNewImageByWidthOrHeight(Image image, int width = 0, int height = 0)
{
    ImageInfoModel_Response _ImageInfoModel_Response = new ImageInfoModel_Response();
    Bitmap bitmap = null;

    try
    {
        int newHeight = 0;
        int newWidth = 0;

        if (width > 0)
        {
            newWidth = width;
            newHeight = newWidth * image.Height / image.Width;
        }
        else
        {
            newHeight = height;
            newWidth = newHeight * image.Width / image.Height;
        }

        bitmap = new Bitmap(newWidth, newHeight); //创建一定高宽度的矩形图片,默认是黑色背景

        using (Graphics graphics = Graphics.FromImage(bitmap)) //从指定的图片里进行绘制内容
        {
            //在指定位置并且按指定大小绘制指定的图片
            graphics.DrawImage(image, 0, 0, newWidth, newHeight);

            //保存当前状态
            graphics.Save();
        }
    }
    catch (Exception ex)
    {
        LogHelper.Error(ex);
    }

    return bitmap;
}
#endregion

猜你喜欢

转载自blog.csdn.net/lmy_520/article/details/113793005