代码之家  ›  专栏  ›  技术社区  ›  M Schenkel

使用TJPEGIMAGE组件将BMP转换为JPG时出现问题

  •  5
  • M Schenkel  · 技术社区  · 15 年前

    我有一个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(见下文)。有什么区别?

    5 回复  |  直到 15 年前
        1
  •  1
  •   Roddy    15 年前

    正如其他人所说,jpeg只是 错误的 这种图像的格式-而且高频色度边缘,您可能有一个最坏的情况下的图像为jpeg!

    我建议你拿一份 Paint.Net 尝试以不同格式(PNG、JPEG、GIF、BMP等)保存/预览图像,并了解图像大小、质量和性能之间的权衡。

    我试过用paint.net保存测试图像为jpeg,并获得与delphi提供的完全相同的质量,所以你(或delphi)所做的没有错…

    更新: According to Wikipedia...

    有一个可选的无损模式 在jpeg标准中定义;但是, 这种模式在 产品。

    我想FusionCharts和Photoshop可以指定这种模式。它通常不被使用,因为jpeg通常被认为是有损压缩的同义词。

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

        2
  •  4
  •   Andreas Rejbrand    15 年前

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

    更新

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

    JPG格式应该 从未 可用于照相照片以外的任何其他用途。例如,如果图表、截图等包含完全相同颜色的大面积区域、非常规则的形状等,则在JPG压缩时将显示清晰的人工制品。对于这种类型的光栅图像,请使用PNG。PNG也是一种压缩格式(也是一种非常非常好的格式!)但压缩是非破坏性的。

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

        3
  •  2
  •   Kryvich    13 年前

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

    1)使用tsdjpgegraphic类 the NativeJPG library 而不是德尔菲的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属性!如果在分配之后放置此命令,则库将使用默认值(=80%)进行压缩质量。

        4
  •  1
  •   Community Mohan Dere    10 年前

    正如安德烈亚斯所说,将压缩质量提高到100。如果您想尝试另一个例子,Bob博士(经常如此贡献者)在这里有一篇很好的文章:
    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

        5
  •  0
  •   Dejan Stanič    14 年前

    我认为仅仅设置JPG.CompressionQuality是不够的。 之后还应该调用jpg.compress()来实际压缩图像…

    类似:

    JPG:=tjpegimage.create(); jpg.loadfromfile('foo.jpg'); jpg.dibneeded(); JPG.压缩质量:=25; 压缩(); jpg.savetofile('bar.jpg'); JPG.For();

    HTH 德扬