使用TJpegImage组件将bmp转换为jpg的问题

时间:2010-06-23 13:30:01

标签: delphi

我有一个bmp文件,我正在尝试将其转换为jpeg格式。使用以下代码创建的jpeg失去了很多清晰度。我试过调整许多设置无济于事。

有没有人有一个将bmp文件转换为jpeg的函数?

var
  Bmp: TBitmap;
  Jpg: TJPEGImage;
begin
  Bmp := TBitmap.Create;
  Jpg := TJPEGImage.Create;
  try
    Bmp.LoadFromFile(BmpFileName);
    Jpg.Assign(Bmp);
    jpg.PixelFormat    :=jf24bit;  // or jf8bit
    Jpg.CompressionQuality := 100;
    Jpg.ProgressiveDisplay := False;
    Jpg.ProgressiveEncoding := False;

    Jpg.SaveToFile(JpgFileName);
  finally
    Jpg.Free;
    Bmp.Free;
  end;
end;

更新II 很多人都回应说jpeg不是在这种情况下使用的图形类型。了解。不是为了击败死马,但我已经能够使用其他程序(即Photoshop)并将其转换为漂亮的jpeg。我用来创建图表(fusioncharts)的工具也可以将它导出到漂亮的jpeg(见下文)。有什么区别?

6 个答案:

答案 0 :(得分:4)

如果你想尽可能少地放松,那么你应该尽可能少地压缩,即设置CompressionQuality := 100

<强> 更新

JPG图像格式设计用于照片和类似的光栅图片。 JPG采用破坏性压缩来减小文件大小。然而,对于大质量值(> ~80),这种压缩的视觉效果可以忽略不计,因为照片不包含相同颜色的大区域,非常规则的形状等。

JPG格式永远不会用于除照片之外的任何其他内容。例如,包含完全相同颜色的大区域,非常规则的形状等的图表,屏幕截图等将在JPG压缩时显示清晰的伪像。对于此类光栅图像,请使用PNG。 PNG也是一种压缩格式(非常非常好的格式!),但压缩是非破坏性的。

所以请不要在图表中使用JPG!使用PNG!

答案 1 :(得分:2)

我和你有同样的问题。这是我的解决方案。

1)使用来自the NativeJPG library的TsdJpegGraphic类而不是Delphi的TJPEGImage。它是免费和开源的。

2)代码:

var
  Bmp: TBitmap;
  Jpg: TsdJpegGraphic;
begin
  Bmp := TBitmap.Create;
  Jpg := TsdJpegGraphic.Create;
  try
    Bmp.LoadFromFile(BmpFileName);
    Jpg.CompressionQuality := 100; // !!!
    Jpg.Assign(Bmp);
    Jpg.SaveToFile(JpgFileName);
  finally
    Jpg.Free;
    Bmp.Free;
  end;
end;

在将位图分配给Jpg之前设置CompressionQuality属性非常重要!如果在分配后放置此命令,则库将使用CompressionQuality的默认值(= 80%)。

答案 2 :(得分:1)

正如Andreas所说,将CompressionQuality升级到100。如果你想尝试另一个例子,Bob博士(频繁的SO贡献者)在这里有一个很好的写作:
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5031886.html#

他有使用流方法的代码。我希望得到相同的结果,但你永远不会知道。这是代码:
https://web.archive.org/web/1/http://techrepublic%2ecom%2ecom/html/tr/sidebars/5031886-1.html

答案 3 :(得分:1)

正如其他人所说,JPEG只是这种图像的错误格式 - 而且对于高频色度边缘,你可能有一个最糟糕的JPEG图像! / p>

我建议您获取Paint.Net的副本,并尝试以不同格式(PNG,JPEG,GIF,BMP等)保存/预览图像,并了解图像大小,质量之间的权衡并表现自己。

我尝试用Paint.net保存您的测试图像为JPEG,并获得与Delphi提供的完全相同的质量,因此您(或Delphi)正在做的事情出现了问题......

更新: According to Wikipedia...

  

有一个可选的无损模式   在JPEG标准中定义;然而,   该模式并未得到广泛支持   产品

我猜想FusionCharts和Photoshop有一种指定这种模式的方法。它通常不常用,因为JPEG通常被认为是LOSSY压缩的同义词。

总之,虽然JPEG文件可以支持无损压缩,但JPEG不是理想的格式,因为它没有得到广泛支持。如果你想要无损,PNG仍然是一个更好的选择。 PNG压缩版本的图像比无损压缩JPEG图像小30%(71K vs 101K)

答案 4 :(得分:1)

您只需要在将 bmp 分配给 jpeg 后调用 Compress 方法。这是 CompressionQuality 参数生效所必需的。当 Delphi 执行 Jpg.Assign(Bmp) 时,它只分配 TJPEGImage.FBitmap 字段。

var
  Bmp: TBitmap;
  Jpg: TJPEGImage;
begin
  Bmp := TBitmap.Create;
  Jpg := TJPEGImage.Create;
  try
    Bmp.LoadFromFile(BmpFileName);
    Jpg.Assign(Bmp);
    
    Jpg.CompressionQuality := 100;
    Jpg.Compress; //!!!

    Jpg.SaveToFile(JpgFileName);
  finally
    Jpg.Free;
    Bmp.Free;
  end;
end;

答案 5 :(得分:0)

我认为仅仅设置jpg.CompressionQuality就足够了。 您之后还应该调用jpg.Compress()来实际压缩图像...

类似的东西:

jpg:= TJPEGImage.Create();   jpg.LoadFromFile( 'foo.jpg');   jpg.DIBNeeded();   jpg.CompressionQuality:= 25;   jpg.Compress();   jpg.SaveToFile( 'bar.jpg');   jpg.Free();

HTH, 德扬