标题:向各位大佬们求助,急急急,批量转换尺寸时遇到的灾难^-^
只看楼主
lamblu
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-8-14
结帖率:100%
已结贴  问题点数:10 回复次数:15 
向各位大佬们求助,急急急,批量转换尺寸时遇到的灾难^-^
这段时间需要批量修改图片尺寸,于是就用本网现成的代码,单个转换时没问题,批量转换时就出现‘无内存……’提示,一通出错提示。
查看任务管理器,发现可用内存和空闲内存告急,退出软件后,内存数量恢复正常。
后来多次测试后,还是发现还是以下进程的问题,调用一次,内存就下降的历害,不知道怎么释放其运行后不断占用的内存,
代码如下,请各位指导,谢谢
*原图片尺寸改变现有的图片尺寸
*a=resizeimage("c:\temp\37057.jpg","C:\temp\37057_haOK.jpg",1024,768)

*a=resizeimage("c:\temp\37517.jpg","C:\temp\37057_haOK.jpg",0,0)

*WAIT windows (a)

*!*    Declare INTEGER ShellExecute IN shell32;
*!*        INTEGER hwnd, STRING lpOperation,;
*!*        STRING lpFile, STRING lpParameters,;
*!*        STRING lpDirectory, INTEGER nShowCmd
*!*    = ShellExecute (0, [open], [c:\temp\37517.jpg],[],[], 3) && 原图
*!*    =INKEY(2) && 等待2秒钟再查看新图
*!*    = ShellExecute (0, [open], [C:\temp\37517_ha.jpg],[],[], 3) && 新图


***768,1365,"c:\temp\37517.jpg","C:\temp\37517_h.jpg"
*******************************************
*算法制作:行者孙(QQ:310727570)
*******************************************
FUNCTION resizeimage  &&(pSourceFileNAme as String,pNewFileNAme as String,nWidth as Long,nHeight as long)
LPARAMETERS pSourceFileNAme,pNewFileNAme,nWidth,nHeight
   * PRIVATE pSourceFileNAme,pNewFileNAme,nWidth,nHeight
    *************************************************************************************
    IF FILE(pSourceFileNAme)=.t.
    ELSE
       pSourceFileNAme=.f.
       RETURN .f.
    endif
   
    IF nWidth=0 OR nHeight=0  &&&&自动
       _Screen.AddObject( 'pic', 'Image' )
       _Screen.pic.Picture = pSourceFileNAme
      * ? _Screen.pic.Width, _Screen.pic.Height
      
       *op = Createobject("WIA.ImageFile")
       *op.LoadFile (pSourceFileNAme)
*!*           op = CREATEOBJECT("Image")
*!*           op.picture=pSourceFileNAme
       LOCAL ow,oh,min_cc  &&&&&&&&&&&&&&&&&&&&&&&&& min_cs :最小的那个尺寸
       ow=_Screen.pic.Width
       oh=_Screen.pic.Height
         _Screen.RemoveObject( 'pic' )
       min_cc=600    &&&&&最小尺寸
       IF ow>min_cc AND oh>min_cc
          nHeight=IIF(ow>oh,min_cc,round(min_cc*oh/ow,0))
          nWidth=IIF(ow>oh,ROUND(min_cc*ow/oh,0),min_cc)
       ELSE
         IF OW<150 OR OH<150
            MESSAGEBOX('转化程序出问T'+pSourceFileNAme,16,'提示')
           *WAIT windows STR(nHeight)+'h/w'+STR(nWidth)
            WAIT windows STR(oh)+'h/w'+STR(ow)
            
            pSourceFileNAme=.f.
            RETURN .f.
         ENDIF
            nHeight=oh
            nWidth=ow
         
       ENDIF
     
      
       *WAIT windows STR(nWidth)+'w/h:'+STR(nHeight)
       RELEASE op
    ENDIF
    *****************************************************************************************8
    DECLARE INTEGER GdiplusStartup IN gdiplus.DLL INTEGER @token, STRING @INPUT, INTEGER OUTPUT
    LOCAL hToken, cInput
    hToken = 0
    cInput = PADR(CHR(1), 16, CHR(0))
    GdiplusStartup(@hToken, @cInput, 0)
     
    DECLARE INTEGER GdipLoadImageFromFile IN gdiplus.DLL STRING wFilename, INTEGER @nImage
    LOCAL nImage
    nImage = 0
    IF GdipLoadImageFromFile(STRCONV(pSourceFileNAme + CHR(0), 5), @nImage)=0
    ELSE
       pSourceFileNAme=.f.
       RETURN .f.
    ENDIF
    #DEFINE   GDIPLUS_PIXELFORMAT_32bppARGB          0x0026200A
    DECLARE INTEGER GdipCreateBitmapFromScan0 IN gdiplus.DLL ;
       INTEGER nWidth, INTEGER nHeight, INTEGER nStride;
       , INTEGER nPixelFormat ;
       , STRING @ cScan0, INTEGER @ nImage
    LOCAL nBitmap, nWidth, nHeight, nX, nY
    nBitmap = 0
    nX = 0
    nY = 0
    IF GdipCreateBitmapFromScan0(nWidth, nHeight, 0, GDIPLUS_PIXELFORMAT_32bppARGB, 0, @nBitmap)=0
    ELSE
       pSourceFileNAme=.f.
       RETURN .f.
    ENDIF
   
    DECLARE INTEGER GdipGetImageGraphicsContext IN gdiplus.DLL ;
       INTEGER nImage, INTEGER @ nGraphics
    LOCAL nGraphics
    nGraphics = 0
    IF GdipGetImageGraphicsContext(nBitmap, @nGraphics)=0
    ELSE
       pSourceFileNAme=.f.
       RETURN .f.
    ENDIF
   
    DECLARE INTEGER GdipDrawImageRect IN gdiplus.DLL ;
       INTEGER nGraphics, INTEGER nImage, SINGLE,SINGLE,SINGLE,SINGLE
       GdipDrawImageRect(nGraphics, nImage, nX, nY, nWidth, nHeight)
   
    LOCAL lcEncoder
    lcEncoder = REPLICATE(CHR(0),16)
    DECLARE INTEGER CLSIDFromString IN ole32 STRING lpsz, STRING @pclsid
    CLSIDFromString(STRCONV("{557CF401-1A04-11D3-9A73-0000F81EF32E}" + CHR(0), 5), @lcEncoder)
    DECLARE INTEGER GdipSaveImageToFile IN gdiplus.DLL ;
       INTEGER nImage, STRING wFilename, STRING qEncoder, INTEGER nEncoderParamsPtr
    ERASE (pNewFileNAme)
    DECLARE Long GdipDisposeImage IN Gdiplus.dll Long nativeImage
    GdipDisposeImage(nImage)
    GdipSaveImageToFile (nBitmap, STRCONV(pNewFileNAme,5) + CHR(0), lcEncoder, 0)
    DECLARE INTEGER GdiplusShutdown IN gdiplus INTEGER token
    GdiplusShutdown(hToken)
    CLEAR DLLS  
    #UNDEF GDIPLUS_PIXELFORMAT_32bppARGB         
    pSourceFileNAme=.t.
     
    RETURN .t.
ENDFUNC

[此贴子已经被作者于2023-2-1 03:41编辑过]

搜索更多相关主题的帖子: IF temp INTEGER jpg STRING 
2023-02-01 02:18
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:2 
是不是内存泄漏,资源分配和释放没处理好。
如下面的语句全程只运行一次就可以
DECLARE ...... ...... IN ...... ...
GdiplusStartup(@hToken, @cInput, 0)
GdiplusShutdown(hToken)
过程中执行到RETURN时要考虑有什么资源要释放。
GDI函数好多时会涉及到“句柄”这东西,实质是一个数据结构,与内存分配有关,不用时要释放。



2023-02-01 07:31
wengjl
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:108
帖 子:2175
专家分:3785
注 册:2007-4-27
得分:2 
照片缩小工具.rar (310.58 KB)


网上得来的工具,给你

只求每天有一丁点儿的进步就可以了
2023-02-01 08:23
csyx
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:29
帖 子:484
专家分:1827
注 册:2018-3-13
得分:2 
调用myfll的Thumbnail、ImageConver如何?
2023-02-01 09:01
igaoyuan
Rank: 2
等 级:论坛游民
帖 子:84
专家分:49
注 册:2022-12-19
得分:2 
以下是引用lamblu在2023-2-1 02:18:54的发言:

单个转换时没问题,批量转换时就出现‘无内存……’提示,一通出错提示。
查看任务管理器,发现可用内存和空闲内存告急,退出软件后,内存数量恢复正常。
后来多次测试后,还是发现还是以下进程的问题,调用一次,内存就下降的历害,不知道怎么释放其运行后不断占用的内存,


先不看代码(说实话也不太懂),如果单个转换没有问题,那么先尝试单个转换,转换完成后查看内存占用情况,如果变化不明显,可以再单独转换5-10个文件,在查看任务管理器情况,那么无非两种情况
1、内存没有太大变化
2、内存不断减少
实际上已经发现
“退出软件后,内存数量恢复正常。

那么软件释放内存是没有问题的,很可能出现在批量循环设计上,是否一次读入过多的图片进入内存?
2023-02-01 10:05
吹水佬
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:432
帖 子:10064
专家分:41463
注 册:2014-5-20
得分:0 
“退出软件后,内存数量恢复正常。”
这时进程已经关闭,系统会自动收回分配给进程的资源,并不等于说进程运行时没有问题。

2023-02-01 11:24
igaoyuan
Rank: 2
等 级:论坛游民
帖 子:84
专家分:49
注 册:2022-12-19
得分:0 
回复 6楼 吹水佬
对对,想简单了
那楼主少加载图片试试,比如一次5-10个,查看一下,50-100个再查看...
2023-02-01 11:52
lamblu
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-8-14
得分:0 
以下是引用igaoyuan在2023-2-1 11:52:06的发言:

对对,想简单了
那楼主少加载图片试试,比如一次5-10个,查看一下,50-100个再查看...

****************************************************************************
一次传5-10,不会崩溃,但可用物理内存持续减少,50-100个就基本就无内存可用了,内存就溢出了
2023-02-01 13:59
lamblu
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-8-14
得分:0 
以下是引用csyx在2023-2-1 09:01:40的发言:

调用myfll的Thumbnail、ImageConver如何?

也试过,同样是这个问题,吃内存历害
2023-02-01 14:00
lamblu
Rank: 1
等 级:新手上路
帖 子:6
专家分:0
注 册:2010-8-14
得分:0 
以下是引用吹水佬在2023-2-1 07:31:07的发言:

是不是内存泄漏,资源分配和释放没处理好。
如下面的语句全程只运行一次就可以
DECLARE ...... ...... IN ...... ...
GdiplusStartup(@hToken, @cInput, 0)
GdiplusShutdown(hToken)
过程中执行到RETURN时要考虑有什么资源要释放。
GDI函数好多时会涉及到“句柄”这东西,实质是一个数据结构,与内存分配有关,不用时要释放。

吹版应该是你说的“资源分配和释放没处理好”,无从下手啊close data,clear all ....全都搞了遍,
就是无法释放内存空间,估计是进程里,生成图片时占用了内存,没有被释放,用MYFLL也是这个梗。
劳烦帮我们研究下
2023-02-01 14:16



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-511200-1-1.html




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

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