Delphi TImage:如何显示比正在加载或分配到的TImage组件大的图像?

Delphi TImage:如何显示比正在加载或分配到的TImage组件大的图像?,image,delphi,bitmap,jpeg,srgb,Image,Delphi,Bitmap,Jpeg,Srgb,Delphi的TImage控件中未显示以下格式的某些JPEG文件 问题解决了。。默认情况下,图像控件中的[TImage.Autosize]复选框未选中,因此图像未调整大小。我在做这个项目 并将速度与我现有的灰度代码进行比较。他们使用的扫描线过程似乎比我目前使用的扫描线过程稍快。对于处理图像的人来说,这是一个很好的起点。当我遇到这个问题并注意到文件大小时,我添加了标准jpeg转换代码和滚动框。我相信这个问题是正确的,但我把它改写了。如果我找到另一个相关的答案,而这个问题更容易找到,我会把这篇文

Delphi的
TImage
控件中未显示以下格式的某些JPEG文件

  • 问题解决了。。默认情况下,图像控件中的[TImage.Autosize]复选框未选中,因此图像未调整大小。我在做这个项目
并将速度与我现有的灰度代码进行比较。他们使用的扫描线过程似乎比我目前使用的扫描线过程稍快。对于处理图像的人来说,这是一个很好的起点。当我遇到这个问题并注意到文件大小时,我添加了标准jpeg转换代码和滚动框。我相信这个问题是正确的,但我把它改写了。如果我找到另一个相关的答案,而这个问题更容易找到,我会把这篇文章。如果没有,我就不谈了

例如,尼康数码相机

尺寸:宽5184 x高3888
垂直分辨率:300 dpi
颜色表示:sRGB
压缩位/像素:2
位深度:24
EXIF版本:0230
属性:N

从三星手机摄像头:

尺寸:宽4128 x高2322
水平和垂直分辨率:72 dpi
颜色表示:sRGB
分辨率单位:2
压缩位/像素:[空白]
位深度:24
EXIF版本:0220
属性:A

Adobe Photoshop中的灰度文件:

尺寸:宽1800 x高3600
水平和垂直分辨率:300 dpi
颜色表示:未校准
压缩位/像素:[空白]
位深度:8
EXIF版本:[空白]
属性:A

一个与上一个文件格式相同但尺寸小得多的文件可以工作

一个工作文件的尺寸:宽570 x高248

具有24位深度、更小尺寸且无分辨率或压缩设置的文件也能正常工作

当我尝试使用下面的代码显示图片时,失败文件上的图片始终为空,并且不会返回任何错误。它与许多其他
jpg
bmp
文件完美结合

sRGB格式的文件是否需要转换?控件在屏幕上显示的内容是否有大小限制?如果是,有没有办法显示更大的文件

procedure TForm1.btnBrowseClick(Sender: TObject);
var
  bmp: TBitmap;
  c2g: TColor2Grayscale;
  ba: TBitmapAccess;
  sw: TStopwatch;
  jpg : TJPEGImage; // jpeg does not show 32-bit support in Delphi, only 24 and 8.
  path, name, ext : string;
  alreadyGray : boolean;
begin
  bmp := TBitmap.Create;
  jpg := TJPEGImage.Create;

  OpenPicturedialog1.InitialDir := FindImageFolder(true);
  if OpenPictureDialog1.Execute() then
  try
    name := OpenPictureDialog1.FileName;
    path := ExtractFilePath(name);
    ext := Lowercase ( ExtractFileExt(name) );

    alreadyGray := false;

    try
      if ( ext = '.jpg' ) or ( ext = '.jpeg' ) then
      begin
        jpg.LoadFromFile(name);
        bmp.Assign(jpg);
        alreadyGray := jpg.Grayscale;
      end
      else
        bmp.LoadFromFile( name );
    except
      on err: Exception do
      begin
        ShowMessage(err.Message);
        Exit;
      end;
    end;

    if bmp.PixelFormat = pfDevice then
      bmp.PixelFormat := pf32bit;

    Image1.Picture.Assign(bmp);

    if alreadyGray then
    begin
      Image2.Picture.Assign(bmp);
      Exit;
    end;

  finally
    jpg.Free;
    bmp.Free;
  end;
end;

由于加载JPEG图像时没有出现错误,我怀疑问题可能出在从
TJPEGImage
TBitmap
的转换中。除非您要操作图像像素,否则根本不需要转换,您可以将原始的
TJPEGImage
直接指定给
TImage
。VCL的
t图像
类使用派生的
t图形
类,因此它可以以其本机格式显示图像,您应该利用该功能,例如:

procedure TForm1.btnBrowseClick(Sender: TObject);
var
  jpg: TJPEGImage;
  bmp: TBitmap;
begin
  OpenPicturedialog1.InitialDir := FindImageFolder(true);
  if OpenPictureDialog1.Execute then
  begin
    Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

    if Image1.Picture.Graphic is TJPEGImage then
    begin
      if TJPEGImage(Image1.Picture.Graphic).Grayscale then
      begin
        Image2.Picture.Assign(Image1.Picture.Graphic);
      end else
      begin
        jpg := TJPEGImage.Create;
        try
          jpg.Assign(Image1.Picture.Graphic);
          jpg.Grayscale := True;
          Image2.Picture.Assign(jpg);
        finally
          jpg.Free;
        end;
      end;
    end else
    begin
      bmp := TBitmap.Create;
      try
        bmp.PixelFormat := pf32bit;
        bmp.Assign(Image1.Picture.Graphic);
        ...
        Image2.Picture.Assign(bmp);
      finally
        bmp.Free;
      end;
    end;
  end;
end;

更新:我在Windows7上的XE2中做了一些测试,发现了与您相同的问题

如果使用
TImage.Picture.LoadFromFile()
加载JPG,则只有当
TImage.Stretch
TImage.Proportional
属性为True时,JPG才会显示良好。如果两者都设置为False(默认值),则图像显示为空白

如果我先将JPG加载到
TJPEGImage
中,然后将其分配给
TBitmap
,则转换本身工作正常(通过将
TBitmap
保存到
.bmp
文件来证明),并且仅当
Stretch
Proportional
为真时,位图才会显示正常,否则显示空白

因此,作为另一个测试,我尝试使用
TPaintBox
,在其
OnPaint
事件中手动绘制图像。如果我使用
TCanvas.Draw()
以全尺寸绘制图像,它们将显示为空。如果我使用
TCanvas.StretchDraw()
将图像放在'PaintBox'的客户区内,它们显示得很好

因此,我认为
TCanvas
在试图以如此大的尺寸显示图像时可能会遇到内存问题。它与所使用的特定类型的JPG(加载良好)无关



更新:别介意我上面说的话。我看到提供的JPG只有非常大的DPI,并且恰好在左上角都是白色的。如果
TImage
/
TPaintBox
的尺寸较大以进行补偿,我现在可以看到图像的全尺寸(更容易看到
TImage
是否放置在
TScrollBox
上且
TImage.AutoSize
设置为True)。这就解释了为什么拉伸/比例绘图可以工作,在需要时拉伸图像以匹配
TImage
的尺寸。

既然加载JPEG图像时没有出现错误,我怀疑问题可能是从
TJPEGImage
TBitmap
的转换。除非您要操作图像像素,否则根本不需要转换,您可以将原始的
TJPEGImage
直接指定给
TImage
。VCL的
t图像
类使用派生的
t图形
类,因此它可以以其本机格式显示图像,您应该利用该功能,例如:

procedure TForm1.btnBrowseClick(Sender: TObject);
var
  jpg: TJPEGImage;
  bmp: TBitmap;
begin
  OpenPicturedialog1.InitialDir := FindImageFolder(true);
  if OpenPictureDialog1.Execute then
  begin
    Image1.Picture.LoadFromFile(OpenPictureDialog1.FileName);

    if Image1.Picture.Graphic is TJPEGImage then
    begin
      if TJPEGImage(Image1.Picture.Graphic).Grayscale then
      begin
        Image2.Picture.Assign(Image1.Picture.Graphic);
      end else
      begin
        jpg := TJPEGImage.Create;
        try
          jpg.Assign(Image1.Picture.Graphic);
          jpg.Grayscale := True;
          Image2.Picture.Assign(jpg);
        finally
          jpg.Free;
        end;
      end;
    end else
    begin
      bmp := TBitmap.Create;
      try
        bmp.PixelFormat := pf32bit;
        bmp.Assign(Image1.Picture.Graphic);
        ...
        Image2.Picture.Assign(bmp);
      finally
        bmp.Free;
      end;
    end;
  end;
end;

更新:我在Windows7上的XE2中做了一些测试,发现了与您相同的问题

如果使用
TImage.Picture.LoadFromFile()
加载JPG,则只有当
TImage.Stretch
TImage.Proportional
属性为True时,JPG才会显示良好。如果两者都设置为False(默认值),则图像显示为空白

如果我先将JPG加载到
TJPEGImage
中,然后将其分配给
TBitmap
,则转换本身工作正常(通过将
TBitmap
保存到
.bmp