CopyRect (масштабирование) с правильными цветами в Delphi

на этот вопрос Я спросил о правильном использовании метода 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. Цвета правильные, если я не изменяю размер.
Как получить 24-битный цвет исходного изображения (JPG), когда изменение размера?

редактировать
Draw не является альтернативой; я хочу скопировать масштабированную версию части исходного изображения.

2 ответов


Это не вызвано из-за уменьшения цвета или неправильного pixelformat и т. д.. Вы, вероятно, уменьшаете изображение во время копирования, и "StretchBlt" сжимает изображение, чтобы вписаться, и в зависимости от режима создает некоторые артефакты. Например, ниже 128x128 image

enter image description here

отображается точно так же, если не специально. Однако при его применении на изображения 90x100 например, выводится

enter image description here.

вы может изменить растяжка режиме для немного лучшего результата:

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

(просмотрев немного графики.pas', VCL, похоже, использует полутон только для 8-битных изображений. Я могу ошибаться или быть прав в этой оценке, но в любом случае режим растяжения полутона не имеет такого ограничения.)


для чего-нибудь лучшего, я считаю, вы должны использовать правильная графическая библиотека.


раз редактировалось:

оказывается, проблема идет против неправильного холста (слишком легко с TImage, если вы к нему не привыкли). Попытался сохранить файлы на моем последнем образце и получил огромный файл на том, который я назначил. Поэтому я начал изучать некоторые другие значения и обнаружил, что вам нужно работать с растровым холстом...

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;

надеемся, что, наконец, получил его. Оййй.