在Delphi中使用正确的颜色进行CopyRect(缩放)

时间:2011-12-03 08:38:54

标签: delphi colors

this question中,我询问了CopyRect方法的正确用法。我得到了一个解决问题的答案,但现在复制的矩形的颜色是错误的(限制为256个值?)。 这是代码:

var
  Bmp: TBitmap;
begin
  Image1.Picture.LoadFromFile(SomeJPGimage);

  Bmp := TBitmap.Create;
  try
    Bmp.Assign(Image1.Picture.Graphic);
    with Bmp do
      Image2.Canvas.CopyRect(Image2.Canvas.ClipRect, Canvas, Canvas.ClipRect);
  finally
    Bmp.Free;
  end;
end;

enter image description here

假色的插图是Image2。如果我不调整大小,颜色是正确的 在调整大小时如何获得源图像(JPG)的24位颜色?

修改
抽奖不是另类;我想复制源图像部分的缩放版本。

2 个答案:

答案 0 :(得分:5)

这不是因为颜色减少或错误的像素格式等引起的。你可能在复制时缩小图像并且'StretchBlt'压缩图像以适应,并且根据模式,会产生一些伪像。例如,以下128x128图像为
enter image description here

如果未应用调整大小,则

显示完全相同。但是,如果将其应用于90x100图像,则输出为
enter image description here

您可以更改stretching mode以获得更好的结果:

var
  Bmp: TBitmap;
begin
  Image1.Picture.LoadFromFile(SomeJPGimage);

  Bmp := TBitmap.Create;
  try
    Bmp.Assign(Image1.Picture.Graphic);

    SetStretchBltMode(Image2.Canvas.Handle, HALFTONE);  // <- here

    with Bmp do
      Image2.Canvas.CopyRect(Image2.Canvas.ClipRect, Canvas, Canvas.ClipRect);
  finally
    Bmp.Free;
  end;
end;

对于上面的源图片,输出现在变为:

enter image description here

(浏览了一些'graphics.pas',VCL似乎只对8位图像使用半色调。在这个评估中我可能是错的或者正确,但无论如何,半色调拉伸模式没有这样的限制。 )


更好的是,我相信,你必须使用合适的图形库。

答案 1 :(得分:4)

再次编辑:

原来这个问题与WRONG画布有关(如果你不习惯的话,用TImage太容易了)。试图保存我最后一个样本上的文件,并在我指定的文件上获得了一个巨大的文件。所以我开始研究其他一些值,发现你需要对Bitmap Canvas ...

var
  BMP: TBitmap;
  MyClipRect: TRect;
begin
  if OpenDialog1.Execute then
     begin
       Image1.Picture.LoadFromFile(OpenDialog1.FileName);
       Bmp := TBitmap.Create;
       try
         Bmp.Assign(Image1.Picture.Graphic);
         myClipRect.Left := (Bmp.Width div 2);
         myClipRect.Top := (Bmp.Height div 2);
         myClipRect.Right := (Bmp.Width);
         myClipRect.Bottom := (Bmp.Height);

         with Image2.Picture.Bitmap do
           begin
             Width := Bmp.Width div 2;
             Height := Bmp.Height div 2;
             Canvas.CopyRect(Canvas.ClipRect, Bmp.Canvas, MyClipRect);
           end;
         Image2.Picture.SaveToFile('image2.bmp');
      finally
        Bmp.Free;
      end;
   end;
end;

希望终于明白了。 Yeesh。