1,问题的提出

公司开发了一个图像压缩上传程序。采用Delphi语言实现。大致步骤如下:

1,上传前将文件打开装载到TJpegImage,

2,创建一个TBitmap组件,设置其大小,采用StretchDraw方法将TJpegImage的图像绘制到TBitmap组件,

3,将TBitmap组件的图像赋值给TJpegImage,

4,设定TJpegImage的压缩率,调用压缩方法执行压缩,

5,最后保存新的图像到文件中

代码如下:

//输入:要转换大小的图片文件路径
//输出:转换后文件的路径
function ConvertJPGFile(const inFile: string): string;
var
img1, img2: TImage;
bmp: TBitmap;
JPEGImage : TJpegImage;
Stream:TFileStream;
i: integer;
const
compress_ratio: array[..] of integer=(,,,,,);
begin JPEGImage := TJpegImage.Create;
bmp := TBitmap.Create; EnterCriticalSection(RTLCriticalSection2);
try
result := GetTempFilePath + ExtractFilename(inFile);
JPEGImage.LoadFromFile(inFile); //要求图像分辨率不小于704×576个像素点
if (1.0 * JPEGImage.Width)/JPEGImage.Height >= (704.0/576.0)
then begin
//原图宽度足够。应以高度为准进行缩小
bmp.Height := ;//新图像高度
bmp.Width := (bmp.Height*JPEGImage.Width) div JPEGImage.Height;//新图像宽度,按比例
end else begin
//原图高度足够。应以宽度为准进行缩小
bmp.Width := ;//新图像宽度
bmp.Height := (bmp.Width*JPEGImage.Height) div JPEGImage.Width;//新图像高度,按比例
end; bmp.Canvas.StretchDraw(bmp.Canvas.ClipRect, JPEGImage);
JPEGImage.Assign(bmp); for i:= to do begin
JPEGImage.CompressionQuality := compress_ratio[i];
JPEGImage.Compress; JPEGImage.SaveToFile(result);
end; finally
JpegImage.Free;
bmp.Free; LeaveCriticalSection(RTLCriticalSection2);
end; end;

此代码在正常环境下执行没有问题,但发现若在子线程中调用,则会频繁出现“Out of system resources”、“存储空间不足,无法处理此命令”等错误。

分析原因可能是JpegImage组件不支持多线程,只在主线程中是安全的。因此,应该在主线程中调用ConvertJPGFile方法。

那么子线程如何让主线程中调用ConvertJPGFile方法呢?转换前后的文件名称如何传递呢?

2,解决思路

可以采用子线程向主线程发送消息,主线程收到消息后,转换图片,然后向子线程发送消息,子线程等到转换完毕的消息后,继续执行。

1,子线程调用postMessage,向主线程发送特定消息WM_5001,然后调用GetMessage函数等候主线程消息

2,主线程的WndProc过程,收到消息WM_5001后,执行图片压缩,然后向子线程PostThreadMessage,发送消息WM_5002

3,子线程收到主线程消息,继续处理

按以上思路 实现后,图片压缩不再出现错误。要说明的是,采用Message的WParam传递字符串参数不可靠,有时会出现字符串截断。因此程序采用全局变量进行参数传递。

3,程序实现

子线程调用:

//调用主线程函数处理图像压缩,否则会出现“out of resource”之类的错误
function Thread_tcp.ConvertJPGFile(inFile: string; var outFile: string;
var outFileSize: integer): Boolean;
var
Msg: tagMsg;
begin
g_convert_fn_in := inFile;
postMessage(GetMainHandler, WM_,,); while GetMessage(Msg,,,) do begin
if Msg.message=WM_ then begin
outFile := g_convert_fn_out;
outFileSize := GetFileSize(outFile); Result := outFileSize>;
Exit;
end;
end; end;

主线程响应:

procedure TfMain.WndProc(var Message: TMessage);
var
fn: string;
p: PChar;
begin
if Message.Msg = WM_ then begin
g_convert_fn_out := ConvertJPGFile(g_convert_fn_in); if getTcpThreadID> then
PostThreadMessage(getTcpThreadID, WM_,,);
end else
inherited; end;

全局变量声明:

var
g_convert_fn_in: string; //转换图片输入文件
g_convert_fn_out: string; //转换图片输出文件 const
WM_=WM_USER+; //子线程向主线程发送消息,由主线程压缩图片
WM_=WM_USER+; //主线程向子线程发送消息,压缩图片完毕

JPEG图像压缩出现资源不足问题的解决的更多相关文章

  1. Oracle报 ORA-00054资源正忙的解决办法

    来源于:http://www.cnblogs.com/loveLearning/p/3625544.html oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT 问题如下: S ...

  2. Oracle 报 ORA-00054资源正忙的解决办法

    oracle之报错:ORA-00054: 资源正忙,要求指定 NOWAIT 问题如下: SQL> conn scott/tiger@vm_database Connected to Oracle ...

  3. 12. thymeleaf中资源相对路径的解决

    把博客部署到tomcat上后才发现因之前资源和链接的地址都是使用的相对路径,这样一来在tomcat上就各种找不到资源.从网上看了几种解决方式都挺麻烦的,且不是适配的,所以我根据thymeleaf的规则 ...

  4. 【spring】静态资源的访问受限解决方法

    前言 我们知道在整合spring mvc框架的时候需要在web.xml中配置一个servlet 代码如下 <!--spring mvc 的DispatcherServlet--> < ...

  5. Vue Cli 打包之后静态资源路径不对的解决方法

    cli2版本: 将 config/index.js 里的 assetsPublicPath 的值改为 './' . build: { ... assetsPublicPath: './', ... } ...

  6. 使用内部Servlet转发JSP后页面的JS,CSS等资源引入问题的解决

    转载自:https://blog.csdn.net/weixin_44353336/article/details/90677792 问题原因 我们在进行web项目开发过程中,经常会在web页面引入一 ...

  7. System.IO.IOException:“找不到资源“window1.xaml”。” 解决方法

    报错:找不到资源"window1.xaml 原因:在编译时使用的是en-US选项进行编译并生成了en-US为名的文件夹,里面包含了可本地化的内容:但是你的本地系统使用的是zh-CN,在你运行 ...

  8. 【图像处理】第三次实验:JPEG图像压缩

    1.任务说明 将LENA图像用JPEG方式压缩. 2.算法原理 JPEG(Joint Photographic Experts Group)是一个由ISO和IEC两个组织机构联合组成的一个专家组,负责 ...

  9. 低配置电脑播放 flash 视频时 占 cpu 资源过高的解决方法

    安装低版本的 flash player 版本, 经调试能满足播放的最低版本是 Flash Player 10.3.183.90 然后 firefox 3.6.28 + Adblock Plus 2.0 ...

随机推荐

  1. python的for else语句

    Python循环中的else语句 绝大部分编程语言中都有条件判断语句,比如 if … else ,在大部语言中,else 一般只在条件判断语句中出现,与 if 语句配套出现,不过在 Python 中, ...

  2. 用yarn替代npm

    最近,从npm拉取vue-cli总失败,后来干脆直接用yarn 全局安装yarn(官网首推用系统包安装,更加安全) npm i yarn -g 用yarn添加全局vue-cli yarn global ...

  3. 【Akka】Actor模型探索

    Akka是什么 Akka就是为了改变编写高容错性和强可扩展性的并发程序而生的.通过使用Actor模型我们提升了抽象级别,为构建正确的可扩展并发应用提供了一个更好的平台.在容错性方面我们採取了" ...

  4. 【智能路由器】让MT7620固件openwrt支持USB

    [智能路由器]系列文章连接 http://blog.csdn.net/u012819339/article/category/5803489 首先确定硬件有USB,这个得检查板子是否引出了usb口,一 ...

  5. python批量删除文件

    敲代码測试时总会碰到要删除日志目录下的日志或者删除一些历史文件.每次都会生成,再測试的时候为了查找错误原因方便总是要在測试前删除这些文件.手动删除比較麻烦.所以写一个批量删除脚本 import os ...

  6. skype默认占用80和443port

    今天把server的port更改为80,结果起不来,报告"port已经被占用"的错误. 使用下列命令找到了元凶: 1. netstat -ano | findstr 80 找到占用 ...

  7. JLabel作为展现元素时需要注意的事项

    如果没有内容,JLabel默认透明就无法作为点击区域了,所以为了让其可以响应鼠标事件需要设置 setOpaque(true) 这样就可以响应鼠标事件了 (吐槽一下,多年以前在大学做个web地图导航的网 ...

  8. codeforces 965E Trie+multiset

    E. Short Code time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. POJ2686 Traveling by Stagecoach 状态压缩DP

    POJ2686 比较简单的 状态压缩DP 注意DP方程转移时,新的状态必然数值上小于当前状态,故最外层循环为状态从大到小即可. #include <cstdio> #include < ...

  10. 第五周 Leetcode 99. Recover Binary Search Tree (HARD)

    Leetcode99 给定一个 二叉搜索树,其中两个节点被交换,写一个程序恢复这颗BST. 只想到了时间复杂度O(n)空间复杂度O(h) h为树高的解法,还没想到空间O(1)的解法. 交换的情况只有两 ...