请两位斑竹 [卷起千堆雪tyn、menxin] 进来看看(100分)

  • 主题发起人 电暖气
  • 开始时间

电暖气

Unregistered / Unconfirmed
GUEST, unregistred user!
请帮忙解决一个问题:jpg压缩过程中一个不理解的问题?
就是在压缩处理后,没有保存压缩后jpeg文件到硬盘前。我没能实现显示压缩后的jpeg图象
在image2上显示。而显示的仍然是压缩前的图象。
因为我想通过调整一个控件TrackBar1.Position滑块的位置[实际上就是调整一个压缩的值]
来实时观看压缩图象的效果,而在此之前我不想每调整一下滑块的位置就保存压缩后的图象
文件。只有认为压缩合适了才可保存。
使用的方法是用流
程序如下:[如有高人,请回答,另外给加分]
procedure TForm1.Button4Click(Sender: TObject);
var
ms1:TMemoryStream;
ms2:TMemoryStream;
jpgstream:TJPEGImage;
bmpstream:Tbitmap;
w_jpg_Length:word; //放置原来没压缩jpeg的文件大小
begin
//---2---初始化
ms1:=TMemoryStream.Create;
ms2:=TMemoryStream.Create;
jpgstream:= TJPEGImage.Create;
bmpstream:=Tbitmap.Create;

//---3---得出原始要压缩文件的大小尺寸-->w_jpg_Length
ms1.clear;
ms1.Position:=0;
ms1.LoadFromFile('C:/My Documents/0008.jpg');
w_jpg_Length :=ms1.Size;
//Edit1.Text :=inttostr(w_jpg_Length);

//---4---
jpgstream.LoadFromFile('C:/My Documents/0008.jpg');
bmpstream.Assign(jpgstream);


//开始压缩,压缩质量的值随滑块变化而变化[范围是1--100,默认=7]
//jpgstream.CompressionQuality:=TrackBar1.Position;
jpgstream.CompressionQuality:=7;
jpgstream.Compress;

//---x---得到压缩后的实际尺寸大小
ms2.Clear;
ms2.Position:=0;
jpgstream.SaveToStream(ms2);
w_jpg_Length :=ms2.Size;
Edit2.Text :=inttostr(w_jpg_Length);

//---x+1---将压缩后的图象显示在image2上[理论是这样想的]
bmpstream.Assign(jpgstream); //此时此刻已经压缩完毕
Image2.Picture.Bitmap.Assign(jpgstream); //实际显示的仍然是没压缩的图象??????why????
//

//---x+2--将压缩后的jpeg文件保存在C:/0008bak.jpg
jpgstream.SaveToFile('C:/0008bak.jpg');

//---x+3---释放资源
bmpstream.free;
jpgstream.free;
ms2.free;
ms1.free;
end;
 
我对图像不是很懂,不过我想这可能是JPEG这个控件的一个BUG.但Delphi没有提供PAS源文件,
所以也不知道改哪儿.应该是它的内存没有清理干净.无论我是将其转到Stream或者是Bitmap
中,效果都一样,没有变.但我将其存到文件中,再读出来时,效果就变了.不知道哪位高人有好
的法子.我只有下面这个笨法子.
//---x+1---将压缩后的图象显示在image2上[理论是这样想的]
bmpstream.Assign(jpgstream); //此时此刻已经压缩完毕-->这一句好像没有用.

//---x+2--将压缩后的jpeg文件保存在C:/0008bak.jpg
jpgstream.SaveToFile('C:/0008bak.jpg');
jpgStream.LoadFromFile('C:/0008bak.jpg'); //再读一次进来,图像就变了.
//如果你的项目急,不妨先这样子应付一下,但这不是好的解决办法,还是要找到原因,从根本上解决才行.

Image2.Picture.Bitmap.Assign(jpgstream); //实际显示的仍然是没压缩的图象??????why????
//

追加一点:用内存流更新更快一点,也不用用存文件.
jpgstream.SaveToStream(ms2);
w_jpg_Length :=ms2.Size;
Edit2.Text :=inttostr(w_jpg_Length);
ms2.position:=0;
jpgstream.LoadFromStream(ms2);//加上这一句,再Assign给BMP就有效果了.
如此,更能说明是TJpegImage的Compress有一个BUG.不知别人有没有更好的法子?
 
个人认为Image2.Picture.Bitmap.Assign(jpgstream),就把流jpgstream从新解压缩了
因为Image2中的是TBitmap类型,你保存时也保存为.bmp
 
我再创建另一个新的new_jpgstream[new_jpgstream:= TJPEGImage.Create;]
将压缩后copy 到流ms2中的数据再copy到--->new_jpgstream
最后再通过new_jpgstream显示到image2上也没有实验成功。

 
不是很清楚呀![:)]
 
Try more, you'll done it!
 
很长时间没有来,让这位朋友久等了.

我的意见还是应用内存流.

var
myjpg:TJpegImage;
mybmp:tbitmap;
ms:tmemorystream;
begin
ms:=tmemorystream.create;
myjpg:=TJpegImage.Create ;
myjpg.Assign (image.picture.bitmap);
myjpg.CompressionQuality :=TJPEGQualityRange(TrackBar1.position);
myjpg.Compress;
myjpg.savetostream(ms);
ms.position:=0;
myjpg.loadfromstream(ms);
mybmp:=tbitmap.Create ;
mybmp.Assign (myjpg);
image.picture.Assign (mybmp);
mybmp.free;
myJPG.free;
ms.free;
end;
 
好久没有这样爽了,太妙了...........卷起千堆雪tyn
 
顶部