Обрезать масштаб и центральное изображение с Delphi - PullRequest
3 голосов
/ 27 ноября 2011

Кто-нибудь знает способ обрезки, масштабирования и центрирования изображения (jpg или растровое изображение) с помощью Delphi?У меня есть изображение с большим разрешением.Я хотел бы иметь возможность масштабировать его до более низкого разрешения.Соотношение целевого разрешения может отличаться от исходного изображения.Я хочу сохранить исходное соотношение сторон фотографии, поэтому я не хочу растягивать изображение до нового разрешения, а обрезать его и выравнивать по центру, чтобы наилучшим образом соответствовать минимальным данным исходного изображения.Кто-нибудь знает, как это можно сделать с помощью Delphi?

Ответы [ 2 ]

4 голосов
/ 27 ноября 2011

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

Вот псевдокод. Реализация будет отличаться в зависимости от того, с чем вы работаете.

// Calculate aspect ratios
sourceAspectRatio := souceImage.Width / sourceImage.Height;
targetAspectRatio := targetImage.Width / targetImage.Height;

if (sourceAspectRatio > targetAspectRatio) then
begin
  // Target image is narrower, so crop left and right
  // Resize source image
  sourceImage.Height := targetImage.Height;
  // Crop source image
  ..
end
else
begin
  // Target image is wider, so crop top and bottom
  // Resize source image
  sourceImage.Width := targetImage.Width;
  // Crop source image
  ..
end;
3 голосов
/ 27 ноября 2011

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

Вам необходимо определить масштаб, в котором нужно нарисовать изображение, а также положение.Я предлагаю вам попробовать эту процедуру:

function CropRect(const Dest: TRect; SrcWidth, SrcHeight: Integer): TRect;
var
  W: Integer;
  H: Integer;
  Scale: Single;
  Offset: TPoint;
begin
  W := Dest.Right - Dest.Left;
  H := Dest.Bottom - Dest.Top;
  Scale := Max(W / SrcWidth, H / SrcHeight);
  Offset.X := (W - Round(SrcWidth * Scale)) div 2;
  Offset.Y := (H - Round(SrcHeight * Scale)) div 2;
  with Dest do
    Result := Rect(Left + Offset.X, Top + Offset.Y, Right - Offset.X,
      Bottom - Offset.Y);
end;

И пример кода вызова:

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormResize(Sender: TObject);
  private
    FGraphic: TGraphic;
  end;

implementation

{$R *.dfm}

uses
  Jpeg, Math, MyUtils;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FGraphic := TJPEGImage.Create;
  FGraphic.LoadFromFile('MonaLisa.jpg');
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FGraphic.Free;
end;

procedure TForm1.FormPaint(Sender: TObject);
var
  R: TRect;
begin
  R := CropRect(ClientRect, FGraphic.Width, FGraphic.Height);
  Canvas.StretchDraw(R, FGraphic);
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  Invalidate;
end;
...