【问题标题】:Problem converting bmp to jpg using TJpegImage Component使用 TJpegImage 组件将 bmp 转换为 jpg 的问题
【发布时间】:2021-04-06 20:47:49
【问题描述】:

我有一个 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;

更新二 很多人反应 jpeg 不是在这种情况下使用的图形类型。明白了。不要打死马,但我已经能够使用其他程序(即 Photoshop)并将其转换为漂亮的 jpeg。我用来创建图表的工具(fusioncharts)也能够将其导出为漂亮的 jpeg(见下文)。有什么区别?

【问题讨论】:

  • 我不知道这是否是问题所在。在将 BMP 分配给 Jpg 之前,您可能需要设置质量设置。转换可能发生在分配而不是保存到文件中。
  • @gbrandt:不,声明在它所在的地方完全没问题。
  • 我对此做了一些跟进。据我所知,在 savetofile 调用期间似乎失去了清晰度。在我的项目中,我添加了一个 TImage 并将 jpeg 分配给它。它渲染得很好。
  • 是的......如果可能的话,JPG 不是正确的格式。

标签: delphi


【解决方案1】:

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

更新

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

JPG 格式绝不可用于除摄影图片以外的任何内容。例如,图表、屏幕截图等包含大面积的完全相同的颜色、非常规则的形状等,在 JPG 压缩时会显示出清晰的伪影。对于这种类型的光栅图像,请使用 PNG。 PNG 也是一种压缩格式(也是一种非常非常好的格式!),但压缩是非破坏性的。

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

【讨论】:

  • 更改 CompressionQuality 不会影响它(我已经更新了原始帖子中的值)。
  • 好的,谢谢。 “大图”的答案似乎是 jpeg 不是适用的图形类型。但是,请阅读我上面的更新 II。看来它实际上可以转换为可观的 jpeg。这是为什么呢?
【解决方案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%)。

【讨论】:

    【解决方案3】:

    正如其他人所说,JPEG 只是那种图像的错误格式 - 由于高频色度边缘,JPEG 可能是最糟糕的图像之一!

    我建议您获取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 与 101K)

    【讨论】:

    • 感谢您的详细回复。所以“大”图片的答案是不使用 jpeg。但我无法理解的是,一些程序如何能够将其保存为 jpeg 格式并且仍然看起来不错。我在上面添加了一个新的 jpeg 文件。这个jpeg如何渲染得很好?
    【解决方案4】:

    正如 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

    【讨论】:

    • 试过了 - 结果一样。能否保证使用 jpeg 和使用 bmp 获得相同的结果?
    • @MSchenkel - 不,jpeg 是一种有损算法,不会给出与 BMP 相同的结果。使用 GIF 或 PNG 以获得最佳效果。 Jpeg 可以满足照片的要求,但您会看到带有屏幕截图、文字、线条图等的“蚊子”伪影。
    【解决方案5】:

    您只需在将 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;
    

    【讨论】:

      【解决方案6】:

      我认为仅设置 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, 德让

      【讨论】:

        猜你喜欢
        • 2012-12-26
        • 2011-10-16
        • 1970-01-01
        • 2013-05-05
        • 2015-05-10
        • 2011-05-29
        • 1970-01-01
        • 2010-10-19
        • 1970-01-01
        相关资源
        最近更新 更多