目錄
【實作效果】
【開篇小敘】
【開發描述】
【簡單設計】
【前端實作簡述】
【后端實作簡述】
【前端完整代碼】
【后端完整代碼】
【實作效果】


【開篇小敘】
新年之際,祝大家在新的一年里牛年大吉、家庭美滿、萬事順利、生意興隆、職位晉升、獎金多多,在情人節里,祝單身的小伙伴們必定找到心中所愛,祝已有佳人的小伙伴們更加幸福甜蜜,所以,小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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/259497.html
標籤:其他
上一篇:Math.random()的使用
