2009-08-07

兼容IE6,IE7,IE8和Firefox的图片上传预览效果

类归于: JavaScript — 标签:, , maker @ 00:29

所谓图片上传预览,就是在使用文件选择框选择了文件之后就可以在页面上看见图片的效果,关于这个效果我一直认为是无法做到的,没想到前不久被zhuozi搞定了。

网上流传的一些关于图片上传预览的代码都是差不多的,IE6下使用文件选择对象的value属性取出将要上传的本地文件路径,然后使用本地路径构造img标签,代码如下:

<input type="file"
onchange="document.getElementById('view').innerHTML=' <img src=\'' + this.value + '\'/>';" />
<div id="view"> </div>

网上有些人说上面的代码可以在IE7下生效,但实际测试是不行的,因为IE7的img标签不支持本地路径,所以需要使用div和css的filter来实现这个效果,代码如下:

<input type="file" onchange=‘javascript:
document.getElementById("pic").filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src
= this.value;’ /><br />
<div id="pic"
style="filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale);
width:400px;height:200px;"></div>

而关于Firefox的图片上传预览效果,网上几乎找不到相关资料,比较容易想到的解决方案无非是自动将图片上传到服务器再显示出来诸如此类,但这里我们不对此类技术进行讨论,我们要做的是正宗的上传前本地预览。

以下是最后的研究结果,同时兼容IE6,IE7,IE8和Firefox

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script>
var picPath;
var image;
// preview picture
function preview()
{
document.getElementById('preview').style.display = 'none';
// 下面代码用来获得图片尺寸,这样才能在IE下正常显示图片
document.getElementById('box').innerHTML
= "<img width='"+image.width+"' height='"+image.height+"' id='aPic' src='"+picPath+"'>";
}
// show view button
function buttonShow()
{
/*
这里用来解决图片加载延时造成的预览失败.
简单说明一下,当image对象的src属性发生改变时JavaScript会重新给image装载图片内容,
这通常是需要一些时间的,如果在加载完成之前想将图片显示出来就会造成错误,所以我们
通过图片的宽度和高度来判断图片是否已经被成功加载,加载完毕才会显示预览按钮.
这里我仍然有一个困惑,在IE7下预览效果偶尔会失效.
*/
if ( image.width == 0 || image.height == 0 ) {
setTimeout(buttonShow, 1000);
} else {
document.getElementById('preview').style.display = 'block';
}
}
function loadImage(ele) {
picPath   = getPath(ele);
image     = new Image();
image.src = picPath;
setTimeout(buttonShow, 1000);
}
function getPath(obj)
{
if(obj)
{
//ie
if (window.navigator.userAgent.indexOf("MSIE")>=1)
{
obj.select();
// IE下取得图片的本地路径
return document.selection.createRange().text;
}
//firefox
else if(window.navigator.userAgent.indexOf("Firefox")>=1)
{
if(obj.files)
{
// Firefox下取得的是图片的数据
return obj.files.item(0).getAsDataURL();
}
return obj.value;
}
return obj.value;
}
}
</script>
</head>
<body>
<input type="file" name="pic" id="pic" onchange='loadImage(this)' />
<input id='preview' type='button' value='preview' style='display:none;' onclick='preview();'>
<div id='box'></div>
</body>
</html>

补充:
上面的代码经过测试貌似不是那么稳定,一些机器上的IE7会失效,我在6台电脑上测试,FF全通过,IE7下有一台没有通过,估计是和IE的设置有关, 而且即使可以正常使用也不是每次都可以成功显示出预览按钮,这个原因也没有找到,估计是图片加载失败什么的,所以例子里特殊处理的预览按钮的显示,即时预览功能失败也不影响其他功能。

下面是在我机器上IE7的测试图片:

image-upload-preview-ie7

2009-03-31

在Symfony中使用第三方图片处理工具WideImage

类归于: PHP, symfony — 标签:, , , maker @ 14:01

最近在整理php的一些库,同时也在研究图片处理的相关功能,所以就发现了WideImage, 虽然是很强大的一个图片处理库,但貌似在国内没有很多人知道。

看了网上很多的图片处理类,功能也就是简单的水印和缩略图,这些WideImage都不在话下,在WideImage源代码中的demos里,我们可以看到转换灰度图,反色,遮罩(Mask)处理,通道(Channels)处理,水印,滤镜,缩放,旋转,翻转和Canvas(我理解也就是在图片上写字)等等功能。

下面简单记录一下如何将WideImage用在symfony中。

首先我们去WideImage的主页(http://wideimage.sourceforge.net/)下载源码包,解包之后会有三个目录,lib,tests,demos,lib是库文件,tests是测试文件,demos中是作者提供的代码示例,可以直接运行访问,要在symfony中使用WideImage,只要将lib目录放在项目的lib目录中就可以。

下面是一些简单的例子:

/**
* 遮罩处理
*/
public function executeMask(sfWebRequest $request)
{
$dir = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR;
$img = wiImage::load($dir.'test.gif');
$mask = wiImage::load($dir.'m.gif');
$img->applyMask($mask, 0, 0)->saveToFile($dir.'mask.png');
return sfView::NONE;
}

/**
* 过滤器和格式转换
*
*/
public function executeFilter(sfWebRequest $request)
{
$dir = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR;
$img = wiImage::load($dir.'test.gif');
$img->applyFilter(IMG_FILTER_GRAYSCALE, 111, 222, 111)->saveToFile($dir.'filter.png');
return sfView::NONE;
}

/**
* 缩放
*/
public function executeResize(sfWebRequest $request)
{
$dir = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR;
$img = wiImage::load($dir.'test.jpg');
$img->resize(100, '30%', 'fill')->saveToFile($dir.'resizefill.jpg');
$img->resize(100, '30%', 'inside')->saveToFile($dir.'resizeinside.jpg');
$img->resize(100, '30%', 'outside')->saveToFile($dir.'resizeoutside.jpg');
return sfView::NONE;
}

/**
* 文字水印
*/
public function executeFont(sfWebRequest $request)
{
$dir = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR;
$img = wiImage::load($dir.'test.jpg');
/*
在图片上输出中文的问题困扰了我很久,有些字体始终是乱码,这里使
用的是方正仿宋简体,可以正常输出UTF-8编码的中文简体字符串。
*/
$font = $dir.'fzfsjt.ttf';
$text = '你好';
$canvas = $img->getCanvas();
$canvas->setFont(new wiFont_TTF($font, 10, $img->allocateColor(0,0,255)));
// 参数 x y text angel
$canvas->writeText(60, 50, $text, 0);
$img->saveToFile($dir.'font.png');
return sfView::NONE;
}

更多的示例请查阅WideImage的主页(http://wideimage.sourceforge.net/)或者查看demos。

2008-12-15

关于上传图片后显示上传图片的路径问题

类归于: symfony — 标签:, kthiz2006 @ 20:39

关于上传图片后显示上传图片的路径问题
在frontend的config里frontendConfiguration.class.php的configure的方法里加上:

<?php

sfConfig::add(array(
'sf_upload_dir_name'  => $sf_upload_dir_name = 'uploadpic',  //指定存放上传图片的目录名
'sf_upload_dir'       => sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.sfConfig::get('sf_web_dir_name').
DIRECTORY_SEPARATOR.$sf_upload_dir_name,  //  指定存放上传图片的目录路径

?>

设置好后,就可以用

<?php

echo image_tag('/'.sfConfig::get('sf_upload_dir_name').'/'.$picname);

?>

显示图片了。

另外一种方便快捷的方法是在settings.yml中设置。

例如:

upload_dir_name:     uploadpic   //上传图片的目录名
upload_dir:          %sf_web_dir%/uploadpic //上传图片的目录的路径

WordPress 所驱动