Results 1 to 12 of 12

Thread: Crop png file

  1. #1

    Crop png file

    Hallo,

    Ik heb een aantal png files waarbij ik telkens een stuk van de afbeelding moet uitsnijden (crop)
    Hiervoor maak ik gebruik van de copy rect functie van het Canvas
    Echter wanneer ik deze code uitvoer krijg ik geen geldig plaatje.

    Code:
      pict := TPngImage.Create;
      bitmap:=TBitmap.Create;
    
      try
       pict.LoadFromFile(FResourcePath+'\projectie-139-muziek-couplet-2-1.png');
       pict.Canvas.CopyRect(rect(0,0,pict.Width,pict.height),bitmap.Canvas,rect(0,0,pict.width div 2,pict.height div 2));
      finally
       pict.Free;
      end;
      bitmap.SaveToFile(FResourcePath+'\test_crop.bmp');
      bitmap.Free;
    Ik had dus verwacht dat ik hiermee het bovenste kwart van het originele bestand in mijn test_crop file zou krijgen.
    Ik heb het ook geprobeerd met een tweede png file i.p.v. een bitmap maar dan krijg ik de melding Canvas doesn't allow drawing

    Wat doe ik verkeerd

  2. #2
    Moet je de gehele PNG verkleinen of wil je slechts een deel van de PNG kopieren? Als je de afbeelding gewoon wilt verkleinen zou ik zoiets doen:
    Delphi Code:
    1. var
    2.   O : TPicture;
    3.   P : TPNGImage;
    4. begin
    5.   O := TPicture.Create;
    6.   P := TPNGImage.CreateBlank(COLOR_RGBALPHA, 16, 100, 100); // Hier zijn de laatste 2 parameters de breedte en hoogte.
    7.   try
    8.     O.LoadFromFile('mypng.png');
    9.     P.Canvas.StretchDraw(TRect.Create(0, 0, P.Width, P.Height), O.Graphic);
    10.     P.SaveToFile('mynewpng.png');
    11.   finally
    12.     O.Free;
    13.     P.Free;
    14.   end;
    15. end;

    Dit is even snel uit mijn hoofd, dus het is maar een voorbeeld.

  3. #3
    Het canvas dat je meegeeft aan CopyRect is de source. Je bent dus een stuk van je PNG aan het overschrijven met een stuk van de lege bitmap i.p.v. andersom.

    Behalve dat, kan het ook zijn dat je de bitmap eerst voldoende groot moet maken. Ik denk niet dat het canvas van de bitmap automatisch groter gemaakt wordt als je erbuiten tekent.
    1+1=b

  4. #4
    Het gaat hierbij dus specifiek om een stuk uit het originele plaatje te halen en dat later weer te gebruiken.
    Dus gee resize maar Crop

    Op aangeven van GolezTrol heb ik de boel omgedraaid echter met het zelfde resultaat
    Code:
      pict := TPngImage.Create;
      bitmap:=TBitmap.Create;
    
      try
       pict.LoadFromFile(FResourcePath+'\projectie-139-muziek-couplet-2-1.png');
       Bitmap.Canvas.Rectangle(rect(0,0,800,600));
       Bitmap.Canvas.CopyRect(rect(0,0,800,600),pict.Canvas,rect(0,0,1600,1200));
    
      finally
       pict.Free;
      end;
      bitmap.SaveToFile(FResourcePath+'\test_crop.bmp');
      bitmap.Free;

  5. #5
    Senior member mzwollo's Avatar
    Join Date
    Oct 2004
    Location
    Larserbos
    Posts
    155
    Deze code doet het wel.

    Code:
      pict   := TPngImage.Create;
      bitmap := TBitmap.Create;
    
      try
        pict.LoadFromFile(FResourcePath + '\projectie-139-muziek-couplet-2-1.png');
        pict.SetSize(pict.width div 2, pict.height div 2); // uitsnijden
        bitmap.SetSize(pict.width div 2, pict.height div 2); // afmetingen bitmap
        bitmap.Canvas.StretchDraw(rect(0, 0, pict.width div 2, pict.height div 2), pict); //tekenen
        bitmap.SaveToFile(FResourcePath + '\test_crop.bmp');
      finally
        pict.Free;
        bitmap.Free;
      end;

  6. #6
    Met de volgende code kan ik wel een plaatje maken echter de crop versie bevat nu het gehele plaatje alleen dan op een resolutie van 800x600
    Het is juist de bedoeling om enkel het stuk van 800x600 pixels uit het orgineel te knippen
    Het is dus nu onbedoeld een resizer geworden.

    Wat doe ik nu fout
    Code:
      pict := TPngImage.Create;
      bmpsource := TBitmap.Create;
      bmpcrop:=TBitmap.Create;
    
      try
       pict.LoadFromFile(FResourcePath+'\projectie-139-muziek-couplet-2-1.png');
       bmpsource.Assign(pict);
       Bmpcrop.Height:=600;
       Bmpcrop.Width:=800;
       BmpCrop.Canvas.CopyRect(BmpCrop.Canvas.ClipRect,bmpSource.Canvas,bmpSource.Canvas.ClipRect);
    
      finally
       pict.Free;
      end;
      bmpSource.SaveToFile(FResourcePath+'\test.bmp');
      bmpCrop.SaveToFile(FResourcePath+'\test_crop.bmp');
      bmpCrop.Free;
      bmpSource.free;

  7. #7
    De code van Mzwolo komt al heel aardig in de buurt (had ik even gemist)
    Echter hier kan je alleen maar een stuk van links boven tot de aangegeven hoogte/breedte er uit knippen
    Uit eindelijk wordt het dus de bedoeling dat je een willekeurig stuk uit het origineel kan knippen

  8. #8
    Yes eindelijk gelukt.
    De denkfout zat dus in de rectangle van de source.

    hiebij de werkende code
    Code:
      pict := TPngImage.Create;
      bmpcrop:=TBitmap.Create;
      try
        pict.LoadFromFile(FResourcePath + '\projectie-139-muziek-couplet-2-1.png');
        bmpcrop.SetSize(800,600); // afmetingen bitmap
        bmpcrop.Canvas.CopyRect(rect(0,0,800,600),pict.Canvas,rect(200,200,1000,800));
        bmpcrop.SaveToFile(FResourcePath + '\test_crop.bmp');
      finally
       pict.Free;
       bmpCrop.Free;
      end;
    Bedankt allemaal voor het meedenken

  9. #9
    Toch nog even een vraagje.
    Het originele png bestand is 60 kB groot de Bitmap gaat naar de 1.83 MB (logisch)
    Hoe converteer ik de bitmap nu naar jpg of png waarbij de filesize ook afneemt
    Heb als test de bmpcrop vervangen door een Timage maar als ik die opsla als jpg blijft de file size 1,83 MB

  10. #10
    Je kunt toch gewoon TJpegimage (uit Vcl.Imaging.jpeg) gebruiken om daarna als jpg op te slaan.

    Zoiets.
    Delphi Code:
    1. var
    2.   jpg:TJpegImage;
    3. begin
    4.    jpg := TJpegImage.Create;
    5.    try
    6.      jpg.CompressionQuality := Quality; //
    7.      jpg.Assign(bmp);
    8.      jpg.SaveToFile(FileName);
    9.    finally
    10.      jpg.Free;
    11.    end;

    TJPEGQualityRange is the type of the CompressionQuality property. The higher the TJPEGQualityRange value (up to a maximum of 100), the better the image quality, but the larger the file size. The lower the TJPEGQualityRange value (to a minimum of 1), the smaller the resulting file size, but at the expense of picture quality.

  11. #11
    Hiermee lukt het idd heel aardig had alleen gehoopt dat ik dit ook direct zou kunnen doen dus zonder tussenkomst van een bitmap
    Helaas geeft dit een foutmelding wanneer ik de copyrect direct op jpg uitvoer
    (jpg.setsize mag ik niet uit voeren en zonder een setsize krijg ik een AV)

    Code:
    function TSheetMusic.LoadImage(aLied: TGezang): string;
    var pict : TPngImage;
        bmpCrop:TBitMap;
        jpg:TJpegImage;
    begin
      pict := TPngImage.Create;
      jpg := TJpegImage.Create;
      bmpCrop:=TbitMap.Create;
      result:='';
      try
        pict.LoadFromFile(FResourcePath+ '\'+ alied.FileName);
        jpg.CompressionQuality := 100;
        jpg.SetSize(1460,900);  //hierop een foutmelding dat ik dit niet mag doen, zonder deze lijn krijg je een AV op de volgende regel
        jpg.Canvas.CopyRect(rect(0,0,1460,900),pict.Canvas,rect(70,140,1530,1040));
        jpg.SaveToFile(FResourcePath + '\temp.jpg');
        Result:= FResourcePath + '\temp.jpg';
      finally
        pict.Free;
        bmpCrop.Free;
        jpg.Free;
      end;
    end;
    Last edited by cpri; 06-May-22 at 17:15.

  12. #12
    Ja, normaal moet dat met een tussen TBitmap.

    Maar je kunt wel een beetje hacken en dit doen (hier is wel de TJPEGImage hack voor nodig):

    Delphi Code:
    1. type
    2.   TJPEGImage = class(Vcl.Imaging.jpeg.TJPEGImage);  // Hack TJpegImage, volatile, deze mag je ook TMyJpegImageHack noemen als je dat ook gebruikt bij .Create
    3. // ...
    4.   pict.SetSize(1460, 900); // crop je PNG image al in TPngImage
    5.   jpg.CompressionQuality := 100; // <- wil je een beetje comprimeren dan moet je geen 100 gebruiken :)
    6.  
    7.   // de volgende 2 regels gebruiken protected variabele en daarvoor is dus die 'hack'
    8.   jpg.NewBitmap; // <- maak nieuwe TBitmap aan in TJpgImage
    9.   jpg.Bitmap.Assign(pict); // <- Nu kunnen we direct een assign op Bitmap doen met de PNG
    10.  
    11.   // jpg.Canvas.CopyRect(rect(0, 0, 1460, 900), pict.Canvas, rect(70, 140, 1530, 1040)); // <- dit is dan niet nodig

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •