祝愿大家身体健康!

 站点注册  找回密码
 站点注册

QQ登录

只需一步,快速开始

查看: 7662|回复: 3

[参考资料] pb处理图片的问题

[复制链接]

[参考资料] pb处理图片的问题

[复制链接]
ehxz

主题

0

回帖

57万

积分

管理员

积分
570784
贡献
在线时间
小时
2011-8-6 09:40:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?站点注册

×
不要在程序中使用PB的自带的编辑图片的OLE,用那东西会损坏二进制信息的,我就遇到过图片的问题。所以要是数据库中的图片你用PB自带的OLE编辑过就可能已经损坏,selectblob可能就会出问题(据说OLE会加密图片信息,使得数据库中的图片只能用OLE控件显示和编辑)。解决办法如下:
保存图片时,不要使用OLE,而是直接用FileRead()来读取图片文件到一个BLOB变量,再用UPDATEBOLB直接存储到数据库去,这样就不会造成数据被修改。下面是我写的批量读取图片文件的程序,是根据项目代号来读取其对应工程图到数据库的程序,项目代号和工程图是一一对应的。

blob lbl_pic , lbl_tem
string ls_path,ls_xmdh,ls_filename
long ll_loop,ll_count,ll_return,ll_flen,ll_filertn,ll_fopen,ll_fopenrtn
long ll_floop,i,ll_bz

ls_path = trim(sle_path.text)    // 除去字符串前后的空格

if ls_path = '' or isnull(ls_path)  then
messagebox("提示","对不起,请先选择好图片文件夹路径!")
return
end if

sqlca.autocommit =true
select count(dataxh) into:ll_loop from temp where ljxmdh  is not null using gtr_sqlcb ;

ll_count = 0
for ll_count = 1 to ll_loop  //循环取刚才导入的数据项目代号名
ls_xmdh = ''
setnull(ll_fopen)
setnull(lbl_pic)
select ljxmdh into :ls_xmdh from temp where dataxh = :ll_count using gtr_sqlcb ;
if ls_xmdh = '' then
continue
else
ls_filename = trim(ls_xmdh) + '.bmp'
ll_flen = FileLength(ls_path + ls_filename)
if ll_flen = -1 then
ll_filertn = messagebox('提示','未找到图片文件:'+ls_filename +'是否继续?',Question!,yesno!)
if ll_filertn = 2 then
return
else
continue
end if
else
if ll_flen > 32765 then
if Mod(ll_flen, 32765) = 0 then
  ll_floop = ll_flen/32765
else
ll_floop = (ll_flen/32765) + 1
end if
else
ll_floop = 1

end if
ll_fopen = FileOpen(ls_path + ls_filename, StreamMode!, Read!)

if ll_fopen = -1 then
ll_fopenrtn = messagebox('提示','读取图片文件:'+ls_filename +'失败,是否继续?',Question!,yesno!)
if ll_fopenrtn = 1 then
return
else
continue
end if
else
for i = 1 to ll_floop
  FileRead(ll_fopen, lbl_tem)
  if i = 1 then
  lbl_pic = lbl_tem
  else   
    lbl_pic = lbl_pic + lbl_tem
  end if
end for
FileClose(ll_fopen)
end if
end if
end if

UPDATEBLOB pgll_jcsj
SET ljgyjt = :lbl_pic
WHERE ljxmdh = :ls_xmdh
USING sqlca;
end for

if sqlca.sqlcode = 0 then
messagebox('提示','图片数据转换成功!')
commit using sqlca;
else
rollback using sqlca;
messagebox('提示','图片数据转换失败!')
end if

编辑图片时,先生成一个临时图片TEMP.BMP(当然你要是保存的其它格式,如JPG也可以),再调用外部工具,如PHOTOSHOP或WIN画图板等编辑,不要使用OLE!
直接使用API

定义API:Function Long ShellExecuteA(Long hwnd,String lpOperation,String lpFile,String lpParameters, String lpDirectory,Long nShowCmd) Library "shell32.dll"   

编辑图片:
long ll_return

if is_bjms = '1' then
ll_return = ShellExecuteA(0,'open',gs_path + "\bmptem\temp.bmp",'','',1)
else
ll_return = ShellExecuteA(0,'edit',gs_path + "\bmptem\temp.bmp",'','',1)
end if

if ll_return = 2 then
messagebox('信息提示','未找到临时文件:'+gs_path + '\bmptem\temp.bmp')
return
elseif ll_return = 31 then
messagebox('信息提示','您还未给位图文件设置编辑工具!')
return
end if

this.enabled = false
ii_bjbs = 1
外部工具打开后,要监控外部程序的状态,同步刷新图片信息。

然后是保存:
long ll_flen,ll_floop,ll_fopen,i
blob lbl_pic,lbl_tem

ii_bjbs = 0
ll_flen = FileLength(gs_path + "\bmptem\temp.bmp")
if ll_flen = -1 then
messagebox('提示','未找到图片文件,保存失败!')
return
else
if ll_flen > 32765 then
if Mod(ll_flen, 32765) = 0 then
ll_floop = ll_flen/32765
else
ll_floop = (ll_flen/32765) + 1
end if
else
ll_floop = 1
end if
ll_fopen = FileOpen(gs_path + "\bmptem\temp.bmp", StreamMode!, Read!)
for i = 1 to ll_floop
FileRead(ll_fopen, lbl_tem)
if i = 1 then
lbl_pic = lbl_tem
else   
lbl_pic = lbl_pic + lbl_tem
end if
end for
FileClose(ll_fopen)
end if

UPDATEBLOB pgll_jcsj
SET ljgyjt = :lbl_pic
WHERE ljxmdh = :is_xmdh
USING sqlca;

if sqlca.sqlcode = 0 then
messagebox('提示','保存成功!')
commit;
else
messagebox('提示','保存失败!')
return
end if

保存完成就可以用FileDelete()删除临时图片文件。

显示图片则可以使用数据窗口的DispalyASPicture属性来显示生成的临时图片


使用以上方法处理图片应该不会再有问题。

/////////
在pb中用selectblob取image类型的数据时,在调试的时候发现变量值是空的,还有可能,图片就没有存进数据库,或者数据损坏了。
BlobMid()
功能从Blob变量中提取出一段数据。提取之后,原Blob变量内容不变。
语法BlobMid ( data, n {, length } )
参数data:Blob类型的数据n:指定要提取数据的起始位置,有效值在1到4,294,967,295之间length:可选项,指定要提取数据的长度,以字节为单位,有效值在1到4,294,967,295之间。缺省时提取从指定位置n到末尾的所有数据返回值Blob。函数执行成功时返回指定字节数的数据。如果n的值大于data的字节数,函数返回空。如果n与length的和超过了data数据的字节数,那么BlobMid()函数返回剩下的数据,数据长度将小于参数length的值。如果任何参数的值为NULL,则BlobMid()函数返回NULL。

尽量不要使用blobmid来处理文件,因为返回值有长度限制,而且很不稳定。希望楼主能进一步说清需求,要如何处理图片,大家可以帮你想办法。
//////////////
三楼你说的是怎么样把图片文件显示出来,但是我现在遇到的问题是要从sql数据库中把image类型的数据读出来,并且能够赋给图片控件。注:是大图片
blob bphoto
int id_no=6,len
selectblob photo into :bphoto from phototable where id = :idno using sqlca;
len = len(bphoto)
这条数据的photo字段在数据库中明明有数据,但就是读不出来,调试跟踪时发现lb_photo为空值,len返回为空,用但是换用下面的语句后,
select photo into :bphoto from phototable where id = :idno using sqlca;
len = len(bphoto)
if  mod(len/32765) then
write = mod(len/32765)
else
write = mod(len/32765) + 1
end if
for cnt = to write
btemep = blobmid(bphoto,(write-1)*32765+1,32765)

next
len却有返回值,而且有50000000多字节,然后我就用循环读取数据,但是在执行到blobmid这句时就死机了。
/////////////////

总结如下:
1.
selectblob photo into :bphoto from phototable where id = :idno using sqlca;
这句有问题啊,你的变量是这样定义的:int id_no = 6  ,但是你的条件是where id = :idno  
变量名字写错了啊,不应该是idno ,而应该是 id_no
2.
len变量不要用int类型,int类型的长度太小,可能图片太大越界了,最好使用long型
3.
图片过大会导致数据提取时得不稳定现象,尽量不要存取太大的图像。
4.
直接把blob赋给图片控件是不可能显示出图片的,我已试验过了,我前面也说了,你如果用PB的OLE编辑过图片,把编辑过的数据存在数据库后,图片的二进制数据会被PB串改加密,同样,pb图片控件也只认这种加密后的二进制数据,直接存在数据库的图片显示是有问题的。所以才告诉你要生成临时图片文件来显示。
4.
不明确你的数据库,我使用
selectblob 图片字段 into:BLOB字段 from 图片表
的方法在ORACLE、informix和ASA中都没有出过问题。
如果你使用的SQL Server 数据库
实在不行就把IMAGE字段的字段类型改为TEXT,再试。


下面一段取图片的程序在我的软件了一直很正常,用户使用了很久了:

selectblob ljgyjt into:lb_image from pgll_jcsj
WHERE ljxmdh = :is_xmdh using sqlca;

ll_flen = len(lb_image)
if ll_flen > 32765 then
if Mod(ll_flen, 32765) = 0 then
ll_floop = ll_flen/32765
else
ll_floop = (ll_flen/32765) + 1
end if
else
ll_floop = 1
end if
ll_fopen = FileOpen(gs_path + "\bmptem\temp.bmp", StreamMode!, Write!, Shared! , Append!)
for i = 1 to ll_floop
setnull(lbl_tem)
if i = 1 then
lbl_tem = blobmid(lb_image,1,32765)
else
j = 32765*(i - 1) + 1
if i = ll_floop then
lbl_tem = blobmid(lb_image,j,ll_flen)
else
lbl_tem = blobmid(lb_image,j,j+32765)
end if

end if
FileWrite(ll_fopen, lbl_tem)
end for
FileClose(ll_fopen)


你的图片不要大于32K,不然会超过PB处理的界限。不行就分成几个字段存储。
共享共进共赢Sharing And Win-win Results
SYBASEBBS - 免责申明1、欢迎访问“SYBASEBBS.COM”,本文内容及相关资源来源于网络,版权归版权方所有!本站原创内容版权归本站所有,请勿转载!
2、本文内容仅代表作者观点,不代表本站立场,作者自负,本站资源仅供学习研究,请勿非法使用,否则后果自负!请下载后24小时内删除!
3、本文内容,包括但不限于源码、文字、图片等,仅供参考。本站不对其安全性,正确性等作出保证。但本站会尽量审核会员发表的内容。
4、如本帖侵犯到任何版权问题,请立即告知本站 ,本站将及时删除并致以最深的歉意!客服邮箱:admin@sybasebbs.com
fuxiaoyang13

主题

0

回帖

3136

积分

论坛元老

积分
3136
贡献
在线时间
小时
2011-8-6 11:36:41 | 显示全部楼层
学习学习!!!!
共享共进共赢Sharing And Win-win Results
migcheng

主题

0

回帖

1万

积分

论坛元老

积分
14678
贡献
在线时间
小时
2011-8-8 01:09:21 | 显示全部楼层
感謝樓主分享
共享共进共赢Sharing And Win-win Results
838637819

主题

0

回帖

337

积分

高级会员

积分
337
贡献
在线时间
小时
2012-12-29 14:38:47 | 显示全部楼层
感謝樓主分享
共享共进共赢Sharing And Win-win Results
您需要登录后才可以回帖 登录 | 站点注册

本版积分规则

免责声明:
本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Admin@SybaseBbs.com

QQ|Archiver|PowerBuilder(PB)BBS社区 ( 鲁ICP备2021027222号-1 )

GMT+8, 2024-4-28 17:45 , Processed in 0.046361 second(s), 7 queries , MemCached On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表