php操作数据库读取出来的图片流并GD编辑图片
这个是切割裁切图片程序的主功能页面,里面主要是通过jcrop这个jq插件实现的核心功能。
大概的流程是,当选中一个图片的时候,先将图片直接upload上服务器,这个是原图,而当你需要裁切的时候,那么那个时候提交的仅仅是裁切的一些参数,比如坐标xy,宽高wh,然后通过这个参数,把从服务器取出来的原图进行GD2库的一些函数代码1:html端
<script type="text/javascript" src="__STATIC__/js/jquery.Jcrop.js">
</script>
<div style="padding:3px;align:center">
<table width="370px">
<tr>
<td width="60%">
原始图:
<br/>
<img src="<{:U('Avatar/getAvatar')}>?sid=<{$server_id}>&rid=<{$role_id}>&rand=xxxx"
id="<{$prefix}>_roleHeadIconPrev" class="<{$prefix}>_roleHeadIconPrev"
alt="avatar" style="width:200px;height:200px;" />
</td>
<td width="40%">
<p style="padding-left:20px;">
<font color="#999999">
支持JPG图片格式,建议尺寸为90px*90px,大小500K以下;
</font>
<br/>
<br/>
预览图:
<br/>
<div style="width:90px;height:90px;overflow:hidden;">
<img src="<{:U('Avatar/getAvatar')}>?sid=<{$server_id}>&rid=<{$role_id}>&rand=xxxx"
id="<{$prefix}>_roleHeadIconTget" alt="<{$prefix}>_roleHeadIconTget">
</div>
</p>
</td>
</tr>
<tr>
<td colspan="2">
<form id="uploadAvatarForm" method="post" enctype="multipart/form-data">
<input type="hidden" name="info[server_id]" value="<{$server_id}>" />
<input type="hidden" name="info[role_id]" value="<{$role_id}>" />
<input type="file" name="upload_avatar" id="inputavatarfile" />
</form>
<p>
<span style="color:#FF0000" id="<{$prefix}>_roleHeadIconTips">
请选择图片后裁切,不裁切将保存原图
</span>
</p>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<div>
<form id="resetAvatarForm" action="" method="post">
<input type="hidden" name="info[server_id]" value="<{$server_id}>" />
<input type="hidden" name="info[role_id]" value="<{$role_id}>" />
<input type="hidden" id="x" name="info[size][x]">
<input type="hidden" id="y" name="info[size][y]">
<input type="hidden" id="w" name="info[size][w]">
<input type="hidden" id="h" name="info[size][h]">
<button type="button" id="<{$prefix}>_btn_savecut" onclick="javascript:cutAvatarImages();">
保存裁切
</button>
<button type="button" id="<{$prefix}>_btn_close" onclick="javascript:close_avatar_upload();">
取消裁切并保存
</button>
</form>
</div>
</td>
</tr>
</table>
</div>
<script>
//这里创建一个图像保存到内存,并没有添加到 HTML 中,只是个参考
var avatarRateX, avatarRateY, avatarRateW, avatarRateH;
//var avatarRateX=1,avatarRateY=1,avatarRateW=1,avatarRateH=1;
function changePreviewSize() {
$("<img/>").attr("src", "<{:U('Avatar/getAvatar')}>?sid=<{$server_id}>&rid=<{$role_id}>&rand=" + Math.random()).load(function() {
var avatarRealSize = this;
/*
$(".<{$prefix}>_roleHeadIconPrev").each(function(index,element){
avatarRateX = avatarRealSize.width/200;
avatarRateY = avatarRealSize.height/200;
//alert(element.style.height);
});*/
avatarRateX = avatarRealSize.width / 200;
avatarRateY = avatarRealSize.height / 200;
//alert(avatarRateY);
});
}
$(document).ready(function() {
changePreviewSize(); //捣鼓一下预览区域的宽高率rate
//2秒捣鼓一下预览区域的宽高率rate
//setTimeout(changePreviewSize(), 2000);
$("#inputavatarfile").change(function() {
$("#<{$prefix}>_roleHeadIconTips").show(1000);
$("#<{$prefix}>_roleHeadIconTips").html("正在上传请稍后...");
//submit the form
$('#uploadAvatarForm').submit();
});
//首次上传
$('#uploadAvatarForm').form({
url: "<{:U('Avatar/uploadImg')}>",
onSubmit: function() {
// do some check return false to prevent submit;
},
success: function(res) {
//alert(res);
if (res > 0) {
//$.messager.alert('提示信息', '操作成功', 'info');
//$("#roleHeadIconAvatarImg")[0].src="<{:U('Avatar/getAvatar')}>?sid=<{$server_id}>&rid=<{$role_id}>&rand="+Math.random();
$("#<{$prefix}>_roleHeadIconTips").html("已选择图片,请裁切!...");
$("#<{$prefix}>_roleHeadIconTips").fadeTo("slow", 0.6);
reloadImgResource(); //从服务器更新全部img资源
changePreviewSize(); //捣鼓一下预览区域的宽高率rate
} else {
$.messager.alert('提示信息', '操作失败,请稍后再试', 'error');
}
},
error: function() {
alert('上传出错');
//$(".loading").hide();
}
});
});
/*
*/
//再次裁切form-裁切按钮
$('#resetAvatarForm').form({
url: "<{:U('Avatar/cropImg')}>",
onSubmit: function() {
changePreviewSize(); //捣鼓一下预览区域的宽高率rate
// do some check return false to prevent submit;
},
success: function(res) {
if (res > 0) {
/**/
$("#<{$prefix}>_roleHeadIconTget").css({
width: "100px",
height: "100px",
marginLeft: "0px",
marginTop: "0px"
});
$("#<{$prefix}>_roleHeadIconTips").html("已裁切成功!...");
$("#<{$prefix}>_btn_savecut").hide("slow");
$("#<{$prefix}>_btn_close").html("设置成功");
$.messager.alert('提示信息', '操作成功', 'info');
reloadImgResource(); //从服务器更新全部img资源
} else {
$.messager.alert('提示信息', '操作失败,请稍后再试', 'error');
}
},
error: function() {
alert('上传出错');
}
});
jQuery(function($) {
// Create variables (in this scope) to hold the API and image size
var jcrop_api, boundx, boundy;
$("#<{$prefix}>_roleHeadIconPrev").Jcrop({
onChange: updatePreview,
onSelect: updatePreview,
aspectRatio: 1
},
function() {
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
});
function updatePreview(c) {
$("#x").val(Math.round(c.x * avatarRateX));
$("#y").val(Math.round(c.y * avatarRateY));
$("#w").val(Math.round(c.w * avatarRateX));
$("#h").val(Math.round(c.h * avatarRateY));
if (parseInt(c.w) > 0) {
var rx = 100 / c.w;
var ry = 100 / c.h;
$("#<{$prefix}>_roleHeadIconTget").css({
width: Math.round(rx * boundx) + "px",
height: Math.round(ry * boundy) + "px",
marginLeft: "-" + Math.round(rx * c.x) + "px",
marginTop: "-" + Math.round(ry * c.y) + "px"
});
};
};
});
function cutAvatarImages() {
//alert('cutAvatarImages');
if (!checkCoords()) return false;
//submit the form
$('#resetAvatarForm').submit();
}
function checkCoords() {
if (parseInt($("#w").val())) return true;
$.messager.alert('提示信息', '请在原图上拖出裁切的选区', 'error');
return false;
};
function reloadImgResource() {
$("img").each(function(index, element) {
//$(this)[index].src = "bbbbbbaa2";
element.src = element.src + "&rand=" + Math.random();
});
return;
}
</script>
而在服务器端是通过php的GD2库进行图片裁切的:
代码2:php更新图片裁切的伪代码
<?php
/**
* 重新设定图片大小
* @param unknown $data 参数,不含二进制图片流
* @return boolean 是否裁切成功
*/
function resetSize($data)
{
$this->serverid = $data['server_id'];
$this->change_game_db();
$info = $data['size'];
if (!empty($info)) {
//print_r($info);die;
//上传图片后切割的最大宽度和高度
$width = 90;
$height = 90;
$imgStream = $this->showAvatarStream($data['server_id'], $data['role_id']);
$temp = tempnam(sys_get_temp_dir(), 'Hsh');
$handle = fopen($temp, 'w+');
fwrite($handle, $imgStream);
$handleSrc = imagecreatefromjpeg($temp);
fclose($temp);
//var_dump($im);exit();
$handleNew = imagecreatetruecolor($width, $height);
//var_dump($handleNew);exit();
imagecopyresampled($handleNew, $handleSrc, 0, 0, $info['x'], $info['y'], $width, $height, $info['w'], $info['h']);
$temp = tempnam(sys_get_temp_dir(), 'Hsh');
imagejpeg($handleNew, $temp, 100);//
$newStream = file_get_contents($temp);
//header('Content-type: image/jpeg');
//echo $imgStream;
//echo imagejpeg($handleNew);
//exit();
$flag = $this->updateAvatar($data, $newStream);
imagedestroy($handleNew);
imagedestroy($handleSrc);
return $flag;
//header('Content-type: image/jpeg');
//echo $imgStream;
//echo imagejpeg($handleNew);
//exit();
}
return false;
}
大致就是这样子了。主要的思路,就是首先file输入框change的时候就将图片丢到服务器,然后如果直接关闭就不进行裁切就这样子了,否则就需要裁切,但是裁切的时候传入的也仅仅是四个参数(当然还包括构成唯一对象的图片id等),然后服务器取出资源,用以下核心对象操作,最后保存新的资源对象:
boolean imagecopyresampled (resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
$dst_image:目标图片resource资源标识符
$src_image:源图片resource资源标识符
$dst_x:目标图片的int开始x坐标
$dst_y:目标图片的int开始y坐标
$src_x:源图片读取区域int的x坐标
$src_y:源图片读取区域int的y坐标
$dst_w:目标画布的int宽度
$dst_h:目标画布的int高度
$src_w:源画布读取的int宽度
$src_h:源画布读取的int高度
其次要注意的是:从数据库base64解压出来的是图片流,而不是图片资源标识符,需要将流保存到唯一的临时文件,然后获取图片标识符,然后进行gd库的操作。