मैं डेल्फी 10.4.2 का उपयोग कर रहा हूं और मैं छवियों को स्केल करने का एक तरीका खोजने की कोशिश कर रहा हूं जो छवि गुणवत्ता को बनाए रखता है और बाहरी पुस्तकालयों का अनुरोध नहीं करता

मैंने यही कोशिश की है, आप {$REGION} में दो परीक्षण पा सकते हैं:

procedure TFrmTestGenImg.Test;
var
  LOldWidth, LOldHeight, LNewWidth, LNewHeight: integer;
  LImageNameIn, LImageNameOut, LExt: string;
  LClass: TGraphicClass;
  LImageIn, LImageOut: TGraphic;
  LBitmap, LResized: TBitmap;
begin
  // Original image: 1366 x 768
  LOldWidth := 1366;
  LOldHeight := 768;
  LNewWidth := 800;
  LNewHeight := 449;

  LImageNameIn := 'C:\temp\Input.png';
  LImageNameOut := 'C:\temp\Output_' + FormatDateTime('yyyy.mm.dd hh.nn.ss.zzz', Now) + '.png';

  LExt := TPath.GetExtension(LImageNameIn);
  Delete(LExt, 1, 1);
  if (CompareText(LExt, 'bmp') = 0) then
    LClass := TBitmap
  else if (CompareText(LExt, 'gif') = 0) then
    LClass := TGIFImage
  else
    LClass := TWICImage;

  LImageIn := LClass.Create;
  try
    LImageOut := LClass.Create;
    try
      LImageIn.Transparent := True;
      LImageIn.LoadFromFile(Trim(LImageNameIn));

      LBitmap := TBitmap.Create;
      try
        LBitmap.PixelFormat := pf24bit;
        LBitmap.Assign(LImageIn);

        {$REGION '1st test'}
        LBitmap.Canvas.StretchDraw(
          Rect(0, 0, LNewWidth, LNewHeight),
          LImageIn);                             // -> poor quality
        LBitmap.SetSize(LNewWidth, LNewHeight);
        LImageOut.Assign(LBitmap);
        {$ENDREGION}

        {$REGION '2nd test'}
        LResized := TBitmap.Create;
        try
          LResized.Assign(LBitmap);
          LResized.Width := LNewWidth;
          LResized.Height := LNewHeight;

          GraphUtil.ScaleImage(LBitmap, LResized, (LNewWidth/LOldWidth));  // -> empty image
          LResized.SetSize(LNewWidth, LNewHeight);

          LImageOut.Assign(LResized);
        finally
          LResized.Free;
        end;
        {$ENDREGION}

        if LImageIn is TWICImage then
        begin
          if (CompareText(LExt, 'jpg') = 0) or (CompareText(LExt, 'jpeg') = 0) then
            TWICImage(LImageOut).ImageFormat := wifJpeg
          else
            TWICImage(LImageOut).ImageFormat := TWICImage(LImageIn).ImageFormat;
        end;
        LImageOut.SaveToFile(LImageNameOut);
      finally
        LBitmap.Free;
      end;
    finally
      LImageOut.Free;
    end;
  finally
    LImageIn.Free;
  end;
end;

जैसा कि आप देख सकते हैं, दूसरे परीक्षण के लिए मैंने GraphUtil.ScaleImage का उपयोग किया लेकिन आउटपुट एक खाली छवि है, इसलिए मुझे यकीन नहीं है कि मैंने इसे सही तरीके से उपयोग किया है, दुर्भाग्य से मुझे इस पद्धति का कोई उदाहरण नहीं मिला है।

1
Marina Finetti 15 सितंबर 2021, 14:06
आप मूल रूप से वेक्टर ग्राफ़िक्स चाहते हैं, न कि रास्टर ग्राफ़िक्स। आप गुणवत्ता को "बनाए" नहीं रख सकते क्योंकि या तो परिवर्तन या पुन: एन्कोडिंग अपरिहार्य है।
 – 
AmigoJack
15 सितंबर 2021, 14:13
मैं समझता हूं कि छवि गुणवत्ता बिल्कुल समान नहीं हो सकती है, लेकिन StretchDraw बहुत कम गुणवत्ता वाला पीएनजी उत्पन्न करता है। मैंने इमेज मैजिक का उपयोग करने की कोशिश की और आउटपुट अच्छा है, लेकिन अगर यह संभव है तो मैं डेल्फी कोड का उपयोग करूंगा
 – 
Marina Finetti
15 सितंबर 2021, 15:06
GraphUtil.ScaleImage वह है जिसका मैं उपयोग करूंगा। लाइन LResized.Assign(LBitmap); हटाएं और इसके बजाय LResized.PixelFormat := pf24bit; जोड़ें
 – 
Tom Brunberg
15 सितंबर 2021, 15:14
धन्यवाद! इस तरह ScaleImage ने आखिरकार एक आउटपुट दिया। हालांकि यह अभी भी बहुत कम गुणवत्ता वाला है ..
 – 
Marina Finetti
15 सितंबर 2021, 15:58

1 उत्तर

सबसे बढ़िया उत्तर
procedure ResizeBitmap(const Bitmap: TBitmap; const NewWidth, NewHeight: integer);
var
  Factory: IWICImagingFactory;
  Scaler: IWICBitmapScaler;
  Source : TWICImage;
begin
    Source := TWICImage.Create;
    try
        Factory := TWICImage.ImagingFactory;
        Source.Assign(Bitmap);
        Factory.CreateBitmapScaler(Scaler);
        Scaler.Initialize(Source.Handle, NewWidth, NewHeight, WICBitmapInterpolationModeHighQualityCubic);
        Source.Handle := IWICBitmap(Scaler);
        Bitmap.Assign(Source);
        Scaler := nil;
        Factory := nil;
    finally
        Source.Free;
    end;
end;
5
dwrbudr 15 सितंबर 2021, 16:36
एक आकर्षण की तरह काम करता है, छवि की गुणवत्ता भी बहुत अच्छी है! शुक्रिया :)
 – 
Marina Finetti
15 सितंबर 2021, 16:49