RSS
 

发布Yii的扩展之tree-extension

18

之前在官方的extensions里发布过,现在提供第二个版本,主要修改了移动时左右节点出错的bug。同时增加了TreeSelectWidget。

具体使用如下:
model里

public function behaviors()
{
    return array(
        'TreeBehavior' => array(
             'class' => 'ext.tree.behaviors.TreeBehavior',
             'id'=>'id',
             'parent_id'=>'parent_id',
             'left'=>'lft',
             'right'=>'rht',
             'level'=>'level',
             'name'=>'name'
        ),
    );
}

————
controller里

public function actions()
{
        return array(
            'treeMoveUp'=>'ext.tree.actions.TreeMoveUpAction',
            'treeMoveDown'=>'ext.tree.actions.TreeMoveDownAction',
            'treeCreate'=>'ext.tree.actions.TreeCreateAction',
            'treeUpdate'=>'ext.tree.actions.TreeUpdateAction',
            'treeLoad'=>'ext.tree.actions.TreeLoadAction',
            'treeDelete'=>'ext.tree.actions.TreeDeleteAction',
            'treeChildren'=>'ext.tree.actions.TreeChildrenAction',
            'treeChildrenParent'=>'ext.tree.actions.TreeChildrenParentAction',
        );
}
public function actionAdmin()
{
    $this->render('admin');
}

—————–
view里

$this->widget('ext.tree.widgets.TreeWidget',array('modelName'=>'Your treeModel'));

————–
默认的树表结构

CREATE TABLE IF NOT EXISTS `tree` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `lft` int(11) NOT NULL,
  `rgt` int(11) NOT NULL,
  `level` int(11) NOT NULL,
  `parent_id` int(11) NOT NULL,
  `name` varchar(256) NOT NULL,
  PRIMARY KEY (`id`)
)

TreeSelectWidget的用法
假如你现在你有一信息表(info),同时有一区域表(area),区域表是无限级分类的,区域Model的behaviors请参考以上写法。信息表又是属于(BELONGSTO)区域表,如某条信息是属于浙江省-温州市。那么信息表里可能存在两字段(province_id,city_id)都指向区域Model,表单如下:

//注:$model代表的是信息
echo $form->labelEx($model,'name');//信息名称
$this->widget('myext.tree.widgets.TreeSelectWidget',array(
	'model'=>$model,
	'modelName'=>'Area',
	'route'=>'info/areaSelect',
	'attributes'=>array('province_id','city_id')
));//信息所属区域

然后在您的InfoController的actions方法里加上

public function actions()
{
	return array(
		'areaSelect'=>'myext.tree.actions.TreeSelectAction',
	);
}

好了,马上尝试一下吧!

下载文件:tree.v2

 
 

Linux下cron的使用

21

cron是一个linux下的定时执行工 具,可以在无需人工干预的情况下运行作业。由于Cron 是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务:

/sbin/service crond start //启动服务

/sbin/service crond stop //关闭服务

/sbin/service crond restart //重启服务

/sbin/service crond reload //重新载入配置

你也可以将这个服务在系统启动的时候 自动启动:

在/etc/rc.d /rc.local这个脚本的末尾加上:

/sbin/service crond start

现在Cron这个服务已经在进程里面 了,我们就可以用这个服务了,Cron服务提供以下几种接口供大家使用:

1.直接用crontab命令编辑

cron服务提供crontab命令 来设定cron服务的,以下是这个命令的一些参数与说明:

crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数

crontab -l //列出某个用户cron服务的详细内容

crontab -r //删除没个用户的cron服务

crontab -e //编辑某个用户的cron服务

比如说root查看自己的cron设 置:crontab -u root -l

再例如,root想删除fred的 cron设置:crontab -u fred -r

在编辑cron服务时,编辑的内容有 一些格式和约定,输入:crontab -u root -e

进入vi编辑模式,编辑的内容一定要 符合下面的格式:*/1 * * * * ls >> /tmp/ls.txt
这个格式的前一部分是对时间的设定,后面一部分是要执 行的命令,如果要执行的命令太多,可以把这些命令写到一个脚本里面,然后在这里直接调用这个脚本就可以了,调用的时候记得写出命令的完整路径。时间的设定 我们有一定的约定,前面五个*号代表五个数字,数字的取值范围和含义如下:

分钟 (0-59)

小時 (0-23)

日期 (1-31)

月份 (1-12)

星期 (0-6)//0代表星期天

除了数字还有几个个特殊的符号就 是”*”、”/”和”-”、”,”,*代表所有的取值范围内的数字,”/”代表每的意思,”*/5″表示每5个单位,”-”代表从某个数字到某个数 字,”,”分开几个离散的数字。以下举几个例子说明问题:

每天早上6点

0 6 * * * echo “Good morning.” >> /tmp/test.txt //注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到root的信箱了。

每两个小时

0 */2 * * * echo “Have a break now.” >> /tmp/test.txt

晚上11点到早上8点之间每两个小 时,早上八点

0 23-7/2,8 * * * echo “Have a good dream:)” >> /tmp/test.txt

每个月的4号和每个礼拜的礼拜一到礼 拜三的早上11点

0 11 4 * 1-3 command line

1月1日早上4点

0 4 1 1 * command line

每次编辑完某个用户的cron设置 后,cron自动在/var/spool/cron下生成一个与此用户同名的文件,此用户的cron信息都记录在这个文件中,这个文件是不可以直接编辑 的,只可以用crontab -e 来编辑。cron启动后每过一份钟读一次这个文件,检查是否要执行里面的命令。因此此文件修改后不需要重新启动cron服务。

2.编辑/etc/crontab 文件配置cron

cron服务每分钟不仅要读一次 /var/spool/cron内的所有文件,还需要读一次/etc/crontab,因此我们配置这个文件也能运用cron服务做一些事情。用 crontab配置是针对某个用户的,而编辑/etc/crontab是针对系统的任务。此文件的文件格式是:

SHELL=/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin

MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号

HOME=/ //使用者运行的路径,这里是根目录

# run-parts

01 * * * * root run-parts /etc/cron.hourly //每小时执行/etc/cron.hourly内的脚本

02 4 * * * root run-parts /etc/cron.daily //每天执行/etc/cron.daily内的脚本

22 4 * * 0 root run-parts /etc/cron.weekly //每星期执行/etc/cron.weekly内的脚本

42 4 1 * * root run-parts /etc/cron.monthly //每月去执行/etc/cron.monthly内的脚本

大家注意”run-parts”这个 参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名了。



 
2 Comments

Posted in 未分类

 

用 Smarty 实现多语言网站

23

用 PHP 实现多语言的正途似乎是 gettext 函数族,但是用 gettext 也有很多不方便的地方,今天实现了一种利用 Smarty 来实现多语言 B/S 应用的方法。最后希望达到的效果是程序中除了切换语言的地方,其它地方能够完全不用关心当前的显示语言,比如同样的 $Tmpl->display( ‘welcome.tpl’ ) 在中文状态下会显示中文的欢迎页面,而在英文状态下就显示英文欢迎页面。

既然对 Smarty 对象的调用方式在不同语言下保持一致,那么就要拿 Smarty 类来开刀啦。Smarty 里面把模版“实例化”的接口有两个,一个是 display(),另外一个是 fetch(),而 display() 内部其实调用了 fetch(),所以关键点就在于改造这里。从 Smarty 派生一个新类 CSmarty,重载其中的 fetch() 和 display() 接口:

  1. class CSmarty extends Smarty
  2. {
  3. function CSmarty()
  4. {
  5. $this->Smarty();
  6. }
  7. function set_dirs( $lang )
  8. {
  9. $base_path = ’2ndboy/’;
  10. $this->template_dir = $base_path . $lang . ‘/templates/’;
  11. $this->compile_dir  = $base_path . $lang . ‘/templates_c/’;
  12. $this->config_dir   = $base_path . $lang . ‘/configs/’;
  13. $this->cache_dir    = $base_path . $lang . ‘/cache/’;
  14. }
  15. function fetch( $template, $cache_id = null, $compile_id = null, $display = false )
  16. {
  17. $this->set_dirs( $_SESSION['lang'] );
  18. if( !$this->template_exists( $template ) )
  19. $this->set_dirs( ’en’ );  // Default language is English
  20. return( parent::fetch( $template, $cache_id, $compile_id, $display ) );
  21. }
  22. function display( $template, $cache_id = null, $compile_id = null )
  23. {
  24. $this->fetch( $template, $cache_id, $compile_id, true );
  25. }
  26. }
  27. ?>

可以看出,上述代码把当前的显示语言设置放在 session 里面,所以还要有针对语言切换操作设置 session 的响应代码:

  1. if( isset( $_REQUEST['lang'] ) )
  2. {
  3. if( 0 == strcasecmp( ‘cn’, $_REQUEST['lang'] ) )
  4. $_SESSION['lang'] = ‘cn’;
  5. else
  6. $_SESSION['lang'] = ‘en’;
  7. header( ’Location: ‘ . $_SERVER['HTTP_REFERER'] );
  8. exit;
  9. }
  10. ?>

假设上述代码放在 index.php 里面,那么用 index.php?lang=en 就可以实现把当前语言切换成英文的操作,注意代码里设置完显示语言后会跳转到 referer 所指的页面,这样处理可以实现切换语言后所在位置不变的效果。

以上的代码实现要求模版路径下的目录结构这样布局:第一级目录采用语言名,如 cn,en 等,各个语言目录内部再按 Smarty 的惯例分成 templates、templates_c、cache 等等。

下面再发挥一下想象力,让程序自动识别用户熟悉的语言,比如老外访问看到的是英文内容,国人访问看到的是中文内容:

  1. session_start();
  2. if( !isset( $_SESSION['lang'] ) )
  3. {
  4. if( strstr( $_SERVER['HTTP_ACCEPT_LANGUAGE'], ‘zh’ ) )
  5. $_SESSION['lang'] = ‘cn’;
  6. else
  7. $_SESSION['lang'] = ‘en’;
  8. }
  9. ?>

其实就是通过分析客户端浏览器可接受的语言来设定默认显示的语言:)

呵呵,其实两年多以前就实现过这个功能,今天是旧瓶装新酒,把之前的实现加以改进放上来晒晒,不知各位看官有收获没?:D

 
2 Comments

Posted in 未分类

 

zend studio 5.5.0下使用svn

21

zend studio 5.5.0的确是太老了,但它又的确是太好用了。所以经常折腾一圈回来,然后再使用它。
现在做什么似乎都离不开SVN,而且zend studio 5.5.0自带的SVN版本已经完全脱离了时代。
所以,
请到http://www.sliksvn.com/en/download下载适合您机器的最新版
按提示安装,完毕后。
打开zend studio-》工具-》首选项-》Source Control,选择SVN,然后设置路径,就是把刚才安装的路径。
OK,搞定了。
顺便提供一个序列号:
注册名称:qq71151461
许可证密钥:27a4f1a112182039

 
 

漂亮的netbeans配色方案下载

18

下载地址
下载过后,别忘了说谢谢^_^,本配色文件由QQ好友【独飞】提供
可以到工具-》选项-》字体和颜色里左下角点导入,直接导入zip文件,不需要解压

 
2 Comments

Posted in 未分类

 

Zend Studio 7.2序列号

17

User Name:qq71151461
License Key:3E6E66886194BE656886194B

 
 

垃圾温州电信

11

近段时间浏览网页时经常弹出民生银行的广告,查看IP为60.190.105.9。
垃圾电信,强制投放广告,电话打过去还不承认,还说我自己电脑中毒,难道温州那么多人跟我中的是同一个病毒?大家也可以去搜索一下这个IP。
大家如果遇到,打一万去骂吧。
以前装网通时,也遇到过,打个电话过去,人家道歉了,并马上就屏蔽广告,态度好多了。

 
 

安装 Ehlib 的方法说明

02

在论坛上经常看到很多新手问一些安装组件的方法,我以前在这个方面也碰到过些问题,也有了一些心得,现在就安装Ehlib组件的方法做个说明:

1、当然是先要卸载以前安装的Ehlib组件了,在菜单的“Component”的“install Packeges”里,选择ehlib XX,选择“Remove”。

2、接下来在库里加入这个控件的引用路径,先新建一个文件夹,比如“D:\Component\Ehlib”(最好把要安装的控件都拷贝到这个Component目录下),然后把下载来的Ehlib压缩包里的Common和delphi7目录下的所有文件拷贝到Ehlib目录下(注意:是把这两个文件夹的所有文件都拷到D:\Component\Ehlib下),选择菜单里的“Tools“里的“EnvironMent Option”,选择“library“标签,在“library path”里加入控件的路径,比如为上面介绍的路径:“D:\Component\Ehlib”,如果你不是在对话框里选择加入路径的话,要在前面加上 “;”号。

2、最后就是要安装组件了,然后打开Ehlib目录下的Ehlib70.dpk,选择“Compile”,编译一下,不要安装,随后再打开dclEhlib70.dpk进行安装,打开以后先“Compile“再选择“install”进行安装,组件面板上会出现Ehlib的组件页。

4、别的控件的安装也与此类似,主要是要找到适合Delphi版本的安装文件,和注意要在库里加入这个的控件的引用路径。记得看一下安装文件下的安装说明,基本上为readme.txt或者是setup.text。

 
1 Comment

Posted in delphi

 

在dbgrid里显示图片的方法

02

在DrawColumnCell事件里

procedure TFormSetting.dbgrd5DrawColumnCell(Sender: TObject;
  const Rect: TRect; DataCol: Integer; Column: TColumn;
  State: TGridDrawState);
var
  Bmp: TBitmap;
begin
  if (Column.Field.DataType=ftBLOB) or (Column.Field.DataType=ftGraphic) then
  begin
    Bmp:=TBitmap.Create;
    try
      Bmp.Assign(Column.Field);
      dbgrd5.Canvas.StretchDraw(Rect,Bmp);
      Bmp.Free;
    Except
      Bmp.Free;
    end;
  end
  else
  begin
  //其他操作
  end;
end;
 
No Comments

Posted in delphi

 

朱瑟里诺先生的预言

02

朱瑟里诺先生(Mr. Juseleeno Nobulega Da Roose音译)他是巴西人,出生於1960年,今年47岁,目前的职业是学校的教师,现在与妻子儿女4人过著很清贫的日子,他是位极平实的市民。他所预言的事件与大灾祸发生之年、月、日,均有明确的指示,其次为了以後若有第三者想确认他预言的真假性,朱瑟里诺都会将他预言的事故之日期与内容,登录在公证事务所或国营邮局里,以方便对方查证   有人问他从几岁开始梦到「预知梦」,他回答说九岁,1969年的时候开始,一天有时梦三件,也曾梦过九件,每天所梦到的次数不一样。他说见到的预知梦都是不知不觉的很自然地出现在他的梦境里,决不是他自己选择的。朱瑟里诺十九岁时,遇到巴西很有名的预言圣人Mr. Francisco shabiz,以後世界性的灾害与事件在他的预知梦中逐渐增加。Mr. Francisco shabiz曾经两次被提名为诺贝尔和平奖的候选人,他是位很有名的特异功能者(通灵者),同时也是位慈善事业家。

首先从他2010年以前的预言中挑选出几件已经发生的世界性大事件与巨大灾害

◎世界贸易中心大厦的第二次攻击,第二次是911同时还有数次恐怖事件   1989年他寄给美国总统与英国领事馆之警告书,1989年10月26日邮寄的警告书也登录在Palana(音译,也许有误)镇,Mr.Klicheeba(音译,也许有误)经营的第一公证事务所。此封警告书中也预言1993年世界贸易中心大厦将会第一次受到攻击,虽然没有预告特定日期,但第二次的攻击很明确地告知2001年9月11日。关於此警告书的结果诚如各位所知,第一次的攻击於警告书寄出的三年半後1993年2月26日,於停车场发生炸弹爆炸案造成伤亡,第二次的攻击则发生於约13年後的2001年9月11日,震惊全世界的「911同时数次恐怖分子攻击事件」。

更令人惊叹的是,此警告预言信函中也记载<> 第二次发生攻击事件後,阿富汗与伊拉克战争爆发,伊拉克战败後,海珊总统会潜逃到伊拉克中部的Ad Dawr镇之一处避难所隐藏等等,都详细预告,诚如各位读者已知的事件,在这些警告书中所预言的事件都逐一发生了。

◎印尼苏门答腊海上大地震

关於印度洋海啸的警告书於1996年9月16日寄给驻在巴西首都巴西利亚的印度大使。此警告书中预言2004年12月26日早晨在印尼的Aceh亚齐省会发生8.9级地震,印尼与印度会被10米高的海啸袭击。1997年4月30日寄给印尼Megawati Sukarnoputri梅加瓦蒂总统之警告书,此警告公函之内容如下所述:「我在梦中见到2004年12月26日早晨7点,南亚洲将会被8.9级之超大地震侵袭,同时也会引发10米高的海啸,波及范围将从印尼的Aceh省开始,印度、马来西亚、斯里兰卡、秦国、马尔地夫、孟买,更扩大到摩里西斯等地。而且一定会有一万的生命被夺走……」   其结果,果真如警告书中预言地震发生於12月26日早晨7点58分,死亡人数超过20万人,最大的海啸高达30米,有很多人被涌上来的海啸吞没了。其他如印尼、菲律宾、秦国等国的大使馆也都发送同样的公函,这些公函上全都盖有邮局发送证明之邮戳。并且朱瑟里诺先生也收到从以上各国的大使馆或总统秘书官寄来的感谢函。   从梅加瓦蒂总统府寄来的感谢信函中,很感叹地写道:「关於地震与海啸如果於2004年发生的话,为了要预防此悲惨的灾难发生,有很多事情我们不得不去做,但是我们又无能为力。」另外,从印尼大使馆的书信中简单回函如下:「……我们会将此内容传达给本国政府,如果还有其他情报追加的话,请勿吝惜通知。」   由此可知,於灾害发生的8年前,朱瑟里诺就已经预告会有死亡人数超过20万人的超级大地震与大海啸侵袭南亚,从以上的警告书中详细所述我们得知,朱瑟里诺也都个别发送公函将地震海啸之规模、发生之年月日及时间,全部详细内容通知会遭到波及的邻国,但是实际上他们都没有采取任何适当的预防措施。

以下是他关于2010年到2043年的预言

◎2010年

●2010年在南非举行的世界杯的名次为::第一名:巴西 第二名:德国第三名:法国 第四名:英格兰

●非洲的数个国家之气温可能高达摄氏58度,同时发生严重的缺水。

非洲的温度会高达摄氏58度,初耳闯似乎很难相信的数字,但事实上听今年(07年)的5月初,到过非洲周围旅行过的人所言,Greece希腊与 Turkey土耳其的气温已高达摄氏39~40度,而伊拉克与阿拉伯半岛的主要都市则持续高达摄氏45~46度的酷热高温,夏天的最高温也许有可能。但5 月初就如此高温,可想而知到2010年的夏天地球温暖化会越严重,非洲各国的气温十分有可能创下想像以外之高温。

●6月15日纽约的股票市场会崩盘,世界的经济将陷入危机状态。

◎2011年

●癌症的治疗方法研究成功,但另一种新的病症又会发生。

●致命性的病毒会出现,被命名为失去免疫力的「ALS」(音译,也许有误),如果感染上此病只要4小时即会死亡。

●乌类禽流感H5N1型正式的感染给人类,到2013年止约有7,300万人病死。 朱瑟里诺先生预言的特徵不只能预告传染病与地震之发生,甚至未发生的疾病与地震的名称都能预知,例如前美国副总统「艾尔.高尔」的有名著作之书名「不愿面对的真相」、龙卷风袭击巴西旧都里约热内卢造成数千人死亡、2011年的威胁性传染病的名称「ALS」、2006年的美国旧金山之超强烈大地震命名为「TheBigOne」等代表性事例。

◎2012年

●由於乾旱而火烧旱田之范围扩大,开始沙漠化,从2015年到2020年间亚马逊的树木会消失。

●从12月6日开始天空变成黑云时代,被称之为气象性混沌。

●由於传染病之蔓延人类开始灭亡。

◎2013 ●脑肿瘤以外的癌症之治疗法研究成功。

●西印度群岛(加勒比海附近诸岛)的巴哈马岛,从11月1日~25日的期间因为火山爆发而发生地震,之後又会引发150米高的超巨大海啸,约80米高的海啸会涌到加勒比海,美国本土、巴西等地也会再冲到15公里~20公里的内陆地。海啸要发生之前海水会沉下约6米深,大量的乌类也会开始移动。 朱瑟里诺先生预告当狗和猫知道有大劫难要来时,它们会想逃离现场,在离现场的24小时前它们会有异常的行动,所以我们可依此做为判断的标准。

◎2014年

●慢慢接近地球的小行星(Planet)有可能与地球发生相撞,此小行星的存在影响世界人类存灭之问题。

◎2015年

●11月中地球的平均气温可能高达摄氏59度,会有很多人被热死,世界的大混乱也随之扩大。

◎2016年

●4月中会发生台风侵袭,中国有大都市会遭到破坏,约有1,000人死亡。

●美国的现任总统乔治布希先生将会跟随那一届的政府紧急撤离,撇下美国人民独自面临危机,美国政府大致的逃难地点会选择中国。

◎2018年

●关於小行星向地球接近之问题,世界各国的政府首脑群集举行对策会议,朱瑟里诺先生於2000年时已经预知,且向NASA美国国家航空暨太空总署发出通告此小行星之存在,2002年6月31日NASA也确认并发表过将此小行星命令为「2002ZNT7」。

◎2019年

●可能会研究出以科学力量来解决的方法,可是如果地球相撞的话,则会造成世界上1/3的人口会被毁灭。朱瑟里诺先生预言小行星会撞上地球的可能性约60%。

●6月日本的东海地区会发生比印尼苏门答腊海上大地震还要强烈的巨大地震,届时日本韩国朝鲜中国台湾等太平洋沿岸地区将面临覆灭危机,中国东南沿海地区也会受到海啸重创。

◎2025年

●天文学家会再发现新的小行星,而且很有可能再度与地球相撞,相撞的可能性约80%。

◎2026年

●7月旧金山会发生超巨大地震,被称为「TheBigOne」,SanAndreasFault圣安德烈斯大断层会被破坏,加州会崩垮掉,很多火山口会重新开启,海啸的高度也会超过150米。 从未来的预言警告中,除了以上的预言之外,还有更令人惊骇的预言,朱瑟里诺先生可以告知的最後预言到2043年:

◎2043年

●世界人口大量减少,约有80%的人死於大劫难中。 届时唯一能大量生存下来的种族只剩下了生活在中国西部的人,就如上一次全球灾难最后只剩下了中国的文明存留至今一个道理他的预言虽然准确率很高,但预言毕竟是预言,其中没说中的也不少。未来的事物会因人们的想法、生活方式、行动的转变而改变,使灾难延期或大难化小、小难化无。

朱瑟里諾说这是上帝通过他来警告世人,这是他的使命。他说希望那些没有被言中的惨事更多些。之所以留底,是想引起世人的重视,避免灾难。

 
 

delphi数据库图片的存取

01

一、 原理介绍–流式数据的类型及其应用
在Dephi中提供了TStream来支持对流式数据的操作。TStream是万流之源。
但由于它是一个抽象类,故不能被直接使用;而要使用其相应的子类,
如:TFileStream 、TStringStream、TMemoryStream、TBlobStream、
TWinSocketStream和TOleStream。TStream提供了统一、简洁的方法来进行数据的读写。
1.)SaveToStream(Stream: TStream ); 作用:将类中的数据写到Stream的当前位置中
2.)LoadFromStream(Stream: TStream); 作用:从当前位置读入Stream里的数据
实际使用时我们基本上只要使用上面两个函数就可以了。

二、所遇到的问题及相应的解决方法
为了节省图像的存储空间和使用更加方便,决定采用JPEG这种图像格式。

(一)所遇到的问题

第一、在Delphi 5中进行画图所用到的组件是TImage,所生成的图像的格式为BMP格式,
而为了节省图像的存储空间,图像在数据库里存储的格式须为JPEG格式,这样就产生了
图像格式转化的需求;而TImage本身并不直接提供这两种图像格式之间的转化。

第二、怎样将存储在Microsoft Access数据库中的图像取出并且显示出来:在Delphi 5
中,能提供这种功能的组件是TDBImage,但该组件却存在着一个很大的缺陷:它所能显
示的图像类型只能是一些图标文件,元文件和BMP文件,而不能支持JPEG格式的图像在
该组件中的显示;但根据实际需要,在Microsoft Access数据库中所存储的图像数据却
是以JPEG格式保存的。

(二)相应的解决方法
为了解决上述两个问题,可以采用目前数据库中一种名为大二分对象(BLOB–Bina
ry Large Object),它是用来处理某些特殊格式的数据的。BLOB在数据库的表中实际上
是以二进制数据的形式存放的。为了处理BLOB字段,可以借鉴一些可视的桌面数据库的
方法。在这里,我们选择了通过内存流的方式来完成;使用内存流,可减少磁盘操作,
大大提高运行效率。
具体的过程和相关的程序代码如下:

1、如何实现在Microsoft Access数据库中的图像存储:
这里是利用TStream的子类TMemoryStream向Microsoft Access数据库中存储图像的。
下面的这段代码是在按了“保存”按钮之后所触发的事件处理程序:

procedure TForm1.Button1Click(Sender: TObject);
var
MyJPEG : TJPEGImage;
MS: TMemoryStream;
begin
MyJPEG := TJPEGImage.Create;
try
  with MyJPEG do
  begin
   Assign(Image.Picture.Graphic);
   MS:=TMemoryStream.create;
   SaveToStream(MS);
   MS.Position:=0;
        Table1.Edit;
         TBlobField(Table1.FieldbyName('Image')).LoadFromStream(MS);
         Table1.Post;
         messagebox(getactivewindow(),'图像保存完毕!','保存',mb_ok);
  end;
 finally
  MyJPEG.Free;
 end;
end;

在这段代码里TStream的子类TMemoryStream利用内存流起到了将BMP格式转化为JPEG格式
的中间桥梁的作用。

2、如何将图像从Microsoft Access数据库中取出并显示出来:
下面的这段代码是在按了“查看图像”按钮之后所触发的事件处理程序:

procedure TForm1.Button1Click(Sender: TObject);
var tempstream:TStringStream;
  tempjpeg:TJPEGImage;
begin
  try
    tempstream:=TStringStream.Create('');
    TBlobField(Query1.FieldByName('Image')).SaveToStream(tempstream);
    tempstream.Position:=0;
    tempjpeg:=TJPEGImage.Create;
    tempjpeg.LoadFromStream(tempstream);
    DBImage1.Picture.Bitmap.Assign(tempjpeg);
 finally
    tempstream.Free;
    tempjpeg.Free;
 end;
end;

这段代码的主要作用是:首先将查询结果中的JPEG图像格式数据保存到TStringStream中去,
然后设置数据指针在TStringStream中的位置为0;接着从TStringStream中读入相关数据,
并把它们赋给TDBImage.Picture.Bitmap,这样一来就实现了将数据库中所存储的JPEG格式的
数据转化为BMP格式,并在TDBImage中将图像显示出来。最后将TStringStream和TJPEGImage
这两个对象释放掉。特别要注意的是不能在设计阶段设置TDBImage的DataField属性,而只能
通过写代码的形式在运行阶段把利用流式数据所转化过来的新格式的图像数据赋给
TDBImage.Picture.Bitmap。

2003-10-7 11:10:00
发表评语»»»

2003-10-7 11:11:44 BMP格式转化为JPEG格式uses Jpeg;

procedure CopyBmpToJpeg(BmpFile,JpegFile:string);
var
Bmp:TBitmap;
Jpeg:TJPEGImage;
begin
Bmp:=TBitmap.create;
Jpeg:= TJpegImage.Create;
try
    Bmp.LoadFromFile(BmpFile);
    Jpeg.Assign(Bmp);
    Jpeg.SaveToFile(JpegFile);
finally
    Bmp.Free;
    Jpeg.Free;
end;
end;

2003-10-7 14:28:34 图片缩放Var B:Tbitmap; //临时位图

Begin
B:=Tbitmap.Create;   //建立临时位图
B.Assign(YourBitmap);   //采用相同色彩深度
With B do
   Begin
     Width:=90;        //临时位图的大小为90x90
     Height:=90;
   End;
B.canvas.StretchDraw(B.canvas.Cliprect,YourBitmap);   //缩放适应
B.SavetoFile(YourFileName);   //保存
B.Free;
End;    //搞定

2003-10-22 10:33:33 JPEG和BMP同时存入,两种不同的方法,文件流和内存流

procedure TForm1.Button1Click(Sender: TObject);
var
fs:TFileStream;
MS: TMemoryStream;
Bmp:TBitmap;
MYJpeg:TJPEGImage;
begin
if OpenPictureDialog1.Execute then
    begin
     if ExtractFileExt(OpenPictureDialog1.FileName) = '.bmp' then
       begin
         Bmp:=TBitmap.create;
         MYJpeg:= TJpegImage.Create;
         MS:=TMemoryStream.create;
         try
           Bmp.LoadFromFile(OpenPictureDialog1.FileName);
           with MYJpeg do
             begin
               Assign(Bmp);
               MS.Position:=0;
               SaveToStream(MS);
               Table1.Edit;
               TBlobField(Table1.FieldByName('ZGZP')).LoadFromStream(MS);
               Table1.Post;
             end;
         finally
           Bmp.Free;
           MYJpeg.Free;
           MS.Free;
         end;
      end
     else
       begin
         fs:=TFileStream.Create(OpenPictureDialog1.FileName,fmOpenRead);
         Try
           Table1.Edit;
           TBlobField(Table1.FieldByName('ZGZP')).LoadFromStream(fs);
           Table1.Post;
         Finally
           fs.free;
         end;
       end;
    end;

2003-11-13 21:03:18 图片的缩放

procedure TForm1.Button1Click(Sender: TObject);
var
b: TBitmap;//原图片
nb: TBitmap;//Resize以后的图片
r: TRect;
begin
b := TBitmap.Create;

if OpenDialog1.Execute then
begin
   b.LoadFromFile(OpenDialog1.FileName);
   nb := TBitmap.Create;

   //你可以自己定义高度和宽度,这里是都变成一半
   nb.Height := b.Height div 2;   //高度变为原来的一半
   nb.Width   := b.Width   div 2;   //宽度变为原来的一半
   r.TopLeft := Point(0, 0);
   r.BottomRight := Point(nb.Width, nb.Height);

   with nb.Canvas do
   begin
     Pen.Style := psDash;
     Brush.Style := bsClear;
     Rectangle(0, 0, nb.Width, nb.Height);
     StretchDraw(r, TGraphic(b));
   end;
   if SaveDialog1.Execute then nb.SaveToFile(SaveDialog1.FileName);
   nb.Free;
end;
b.Free;
end;
 
No Comments

Posted in delphi