| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1479 人关注过本帖
标题:VFP 学习、开发漫谈 (19)
只看楼主 加入收藏
liuxingang28
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:山东济南
等 级:贵宾
威 望:47
帖 子:654
专家分:2167
注 册:2014-2-7
结帖率:96.88%
收藏
 问题点数:0 回复次数:6 
VFP 学习、开发漫谈 (19)
今天,与大伙聊一聊在 VFP 中,有关图片的使用和处理问题。

第一个问题:将图片保存在数据表中,还是保存在服务器的某个文件夹下?

如果图片较大、记录较多,则应该将文件保存在服务器的某个文件夹下。有个网友,存有一万多张图片,每张图片的大小约3-4兆,询问在 VFP 下应该采取哪种存储方式。不说操作速度,仅存储空间就需要至少 40G。 我们都知道,VFP有一个规定,就是单个 *.dbf 或 *.fpt 文件不能超过 2G。因此,这种情况下,将图片保存在服务器的某个文件夹下是唯一的选择。

由于同一文件夹下的文件不能重名,而不同用户上传的文件有可能同名,因此,在服务器上不要以文件的上传名称保存文件,而应该将文件命名为一个不重复的序列号。为此,可以在表中增加 2 个字段,第一个字段命名为“文件名”,字符型,保存文件的真实名称;第二个字段命名为“文件ID”,Integer(AutoInc)类型,保存文件的存储名称。上传文件时,将文件的真实名称写入“文件名”字段,再以“文件ID”作为文件名存储在服务器的文件夹下。由于“文件ID”是自动递增的整数型字段,因此以它命名的文件是不重复的。VFP 有一个 SYS(2015) 函数,可产生一个“唯一”的字符串作为文件名,但总觉得不如“AutoInc”来得踏实。

如果图片不大,则可以考虑将图片保存在数据表中。这种存储方式的好处是,管理起来比较方便。

第二个问题:若将图片保存在数据表中,应该选择哪种数据类型?

如果要保存的图片是位图(*.bmp)格式,则选择 General 数据类型最合适。假设 employee.dbf 的照片字段是 photo,则存入照片时,执行 APPEND GENERAL photo FROM d:\照片.bmp。显示照片时,可在表单上添加一个 OleBoundControl,并将其 ControlSource 属性设置为 Employee.photo,移动记录指针后刷新一下表单即可。

我们都知道,Bitmap 格式的图片未经压缩,占用空间大。实际应用中,通常采用 JPG、GIF 或 PNG 格式。这时,表的数据类型应该选择“Memo(Binary)”类型,即:二进制备注型。存入照片时,执行 APPEND MEMO photo FROM d:\照片.jpg。显示照片时,可在表单上添加一个 Image 控件,并在表单的 Refresh 事件中加入 THIS.Image1.PictureVal = Employee.Photo。若要将表中的图片保存到磁盘上,可执行 COPY MEMO photo TO d:\照片.jpg。删除照片时,执行 BLANK FIELD photo。

有 2 个疑问解释一下:

1. 对于 JPG 格式的图片,为什么不将表的数据类型设为 General 呢? 这是因为 General 类型不仅保存了图片内容,还保存了图片的格式信息。这些信息对于 OleBoundControl 控件是必须的,但对于 Image 控件来说,却是画蛇添足。OleBoundControl 控件只能显示位图,不能显示其他格式的图片。

2. 为什么选择 Memo(Binary) 类型而不是 Memo 类型? 如果我们的运行环境都是中文操作系统,则选择 Memo 类型也是可以的。但若开发的程序用于不同语言的操作系统,有可能因代码页的转换,造成图片无法显示,而 Memo(Binary) 是一种二进制文本格式,不存在此问题。

下面,再来说一说 Image 控件。

Image 控件通过其 Picture 属性或 PictureVal 属性来显示图片,并且可显示大部分图片格式。其 Stretch 属性有三个值:0-Clip 裁剪(默认),1-Isometric 等比填充,2-Stretch 变比填充。这三个属性值中,最难理解的就是默认的“0-Clip”。按照通常的理解,“Clip 剪裁”应该是仅显示图片的一部分,超过图片框的部分被裁剪而不显示。而实际情况并非如此。当我们更改 Image 的 Picture 属性时,图片没有被剪裁,而是显示图片的原始大小。要想达到剪裁效果,必须再重新设置一下 Image 控件的 Height 和 Width。

对于“裁剪”这个概念,我是这样理解的:平时我们用剪刀进行裁剪时,肯定是先准备好纸,再裁剪。为 Image 控件的 Picture 属性赋值,就相当于准备纸张,重新设置 Image 控件的 Height 和 Width 就相当于裁剪。不知道我这样说,对你理解 Stretch 的 “0-Clip”属性值是否有帮助。

利用 Image 控件的 Stretch 属性为“0-Clip”的这一特性,我们可以编写一个获取图片尺寸的自定义函数:
程序代码:
cFile = 'd:\photo.jpg'
? cFile + ' 的尺寸是 '+ GetImageSize(cFile)

* ================================================================
* 功能:获取图片文件的尺寸
* 参数:tcPicture 图片文件
* 返回:字符型,长*宽,文件不存在时返回空串
* ================================================================
FUNCTION GetImageSize(tcPicture)
    LOCAL cRet,oImage
    cRet = ''                             && 保存返回值
    IF FILE(tcPicture)                    && 检测文件是否存在
        oImage = CREATEOBJECT('image')    && 建立图片对象
        oImage.Picture = tcPicture        && 加载图片
        cRet = TRAN(oImage.Width) + '*' + TRAN(oImage.Height)    && 获取图片尺寸
    ENDIF
    RELEASE oImage
    RETURN cRet                           && 返回图片尺寸
ENDFUNC

在存储图片时,对图片格式的选择还是有讲究的。若想显示色彩丰富的图片,选择 JPG 格式较好,而不能选择 GIF 格式,因为 GIF 格式仅能显示 256 色。对于色彩不丰富的图片,比如:程序窗口的截图,选择 GIF 较好,占用空间最小。一个比较有意思的现象是,对于小尺寸(如16*16)的 BMP 图片,按照我们的理解,同样一张图片,保存为 256 色应该比保存为 16 位高彩色或 24 位真彩色占用空间要少。可实际情况并非如此。对于一个 16*16 的 BMP 图片,经测试:256 色最大,约 1.3K;其次是 24 位色,约 900 个字节;16 位色最小,约 600 个字节。大尺寸的 BMP 图片则不存在这种情况。请各位网友不妨测试一下,看我说的情况是否存在。所以,我对命令按钮上显示的 bmp 图片均存储为 16 位高彩色,每张图片约 632 个字节。

当 Image 的 Picture 设置为 bmp 图片时,可以设置 Image 的 BackStyle = 0(透明)。此时,图片中的白色区域会变成透明。其他格式的图片无此功能,对于 Gif 或 PNG 图片来说,只能用图片编辑软件将图片中的某个区域或某种颜色设定为透明。

下面,着重谈一下命令按钮中的图片。一般情况下,我们都设置命令按钮的 Picture 为一个 16*16 的 bmp 图片。VFP 会自动将图片中的白色区域转换为透明。不过,很多用户可能没有注意到这一点。因为 Windows XP 默认主题下,按钮的背景色本身就接近于白色。有时候,这种将白色自动转换为透明色的处理方式会带来问题,特别是在工具栏按钮上显示图片时,图片中的白色转换为透明区域后,显示为灰色,很难看。那么怎样才能将图片边缘的白色转换为透明而保留图片内部的白色呢?要解决这个问题,需要使用掩码图片。掩码图片与原图片大小相同,只是将图片实体部分设定为黑色,图片边缘部分设定为白色,并将图片的颜色深度设置为 2 色(黑白)。保存时,文件名与原文件名相同,扩展名设置为 msk,并与原文件保存在同一个文件夹下。掩码图片的作用就是设置图片中的哪些区域透明、哪些区域不透明。

下面的图片是一个“复制”按钮的截图。其中,按钮的 SpecialEffect 设为“2-Hot Tracking”,第一张图片是未使用掩码图片的显示效果,图片内部的白色被转换成透明,显得不太协调。第二张图片是使用掩码图片后的显示效果,另人满意。第三张图片是掩码图片 Copy.msk 的内容。
图片附件: 游客没有浏览图片的权限,请 登录注册



[ 本帖最后由 liuxingang28 于 2014-4-21 15:14 编辑 ]
搜索更多相关主题的帖子: 服务器 文件夹 图片 开发 记录 
2014-04-21 12:13
tlliqi
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:204
帖 子:15453
专家分:65956
注 册:2006-4-27
收藏
得分:0 
补补课
2014-04-21 14:28
antony521
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:170
专家分:175
注 册:2009-8-20
收藏
得分:0 
好好听老师讲课
2014-04-21 15:45
hu9jj
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:红土地
等 级:贵宾
威 望:400
帖 子:11808
专家分:43421
注 册:2006-5-13
收藏
得分:0 
非常实用的经验

活到老,学到老!http://www.(该域名已经被ISP盗卖了)E-mail:hu-jj@
2014-04-22 06:59
asdf_123000
Rank: 4
等 级:业余侠客
威 望:1
帖 子:273
专家分:227
注 册:2012-12-20
收藏
得分:0 
2014-04-24 20:09
pzyun1985
Rank: 2
等 级:论坛游民
帖 子:106
专家分:18
注 册:2013-4-13
收藏
得分:0 
灰常好
2014-04-30 14:01
ILoveVFD
Rank: 3Rank: 3
等 级:论坛游侠
威 望:3
帖 子:218
专家分:147
注 册:2015-5-2
收藏
得分:0 
篇篇精彩!
2015-05-02 12:05
快速回复:VFP 学习、开发漫谈 (19)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032941 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved