Results 1 to 13 of 13

Thread: Vragen over bitmaps

  1. #1
    Game-Programmer nschagen's Avatar
    Join Date
    Jun 2003
    Location
    Alkmaar
    Posts
    685

    Vragen over bitmaps

    Hoi allemaal.

    Ik had een paar vraagjes over bitmaps:

    1. Wat gebeurt er eigenlijk als ik het pixelformat van een TBitmap verander. word dan alle pixeldata ter plekke naar een nieuw formaat omgezet, of gebeurd er iets anders???

    2. Stel: ik heb een 24bit Bitmap geladen in een TBitmap object.
    Als ik deze uitlees is het toch zo dat elke 3 bytes één pixel voorstellen?? zo ja.. hoe zit het dan met pf15bit?
    is die laatste bit gewoon ongebruikt of zit alle data in groepen van 15 bits op elkaar gepakt. Moelijk om uit te lezen lijkt me

    3. 32Bit's bitmaps hebben toch een 8bit alpha-kanaal??
    Word deze gebruikt bij het drawen van bitmaps of niet??

    Alvast bedankt.
    When things don't go right, Turn left

  2. #2
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    1. Kijk in TBitmap.SetPixelFormat. Ik zie daar een CopyImage call staan. De data moet intern natuurlijk geconverteerd worden, lijkt me.

    2. een 24bits bitmap heeft 3 bytes per pixels (R, G, B ieder een byte).
    pf15bits weet ik niet. nooit gebruikt.

    3. Voor zover ik weet heb je het bij het juiste eind. (Ik maak gebruik van de graphics32 library en maak daar ook gebruik van het alpha-kanaal bij het tekenen). De extra byte heb ik overigens ook voor andere doeleinden "misbruikt".

  3. #3
    EFG's reference library heeft een heleboel nuttige tips over de omgang met kleur e.d.
    http://www.efg2.com/Lab/Library/Delp...hics/Color.htm

    1. Ja, de pixeldata wordt geconverteerd naar het nieuwe formaat
    2. Er worden 2 bytes per pixel gebruikt
    3. Volgens mij niet in de standaard TBitmap, maar er zijn componenten die wel met alpha info overweg kunnen

  4. #4
    Game-Programmer nschagen's Avatar
    Join Date
    Jun 2003
    Location
    Alkmaar
    Posts
    685
    Bedankt voor jullie reacties

    2. Er worden 2 bytes per pixel gebruikt
    Huh... 2 pixels klinkt een beetje onlogisch, waarschijnlijk alleen voor 16 bit formaten?? Voor 24bit bitmaps is 3 pixels zoals EricLang zei inderdaad het meest logisch.

    3. Voor zover ik weet heb je het bij het juiste eind. (Ik maak gebruik van de graphics32 library en maak daar ook gebruik van het alpha-kanaal bij het tekenen). De extra byte heb ik overigens ook voor andere doeleinden "misbruikt".
    Inderdaad Het gaat mij er vooral om dat de alpha-data aanwezig is en niet zozeer of het gebruikt word bij het drawen van bitmaps op elkaar. De volgorde is toch ARGB binnen die 32 bits??
    When things don't go right, Turn left

  5. #5
    Game-Programmer nschagen's Avatar
    Join Date
    Jun 2003
    Location
    Alkmaar
    Posts
    685
    Ik heb nog een vraagje over bitmaps dus stel ik die maar in deze thread.

    Gewone delphi bitmaps ondersteunen geen alfakanaal. daarom wil ik een soort AlphaMask gaan maken (Graphics32 is overkill voor mijn project).
    Dus het liefst een non-palette 8bit formaat waar ik op teken met een soort grijskleur (waarde tussen 0..255).
    Het gaat er alleen om dat ik dus zo'n kleur instel en ga tekenen met de canvasfuncties. en dat als ik scanline gebruik, ik elke waarde (1 byte) kan uitlezen en als alphawaarde kan gebruiken.
    is zoiets mogelijk?? en hoe?
    When things don't go right, Turn left

  6. #6
    FHelpdesk.Disable; hbrouwer's Avatar
    Join Date
    Feb 2007
    Location
    Nieuwendijk
    Posts
    26
    In TBitmap zit volgens mij een mask zoals jij bedoelt standaard ingebouwd onder MaskHandle. Zie voor gebruiksvoorbeeld de thread "transparant bitmaps printen". Volgens mij kan je daar een 8 bits mask gebruiken, ikzelf gebruik geen alpha dus weet niet zeker of dat zo is.

    Zou jij me btw kunnen helpen daarmee, je zegt:
    als ik scanline gebruik, ik elke waarde (1 byte) kan uitlezen en als alphawaarde kan gebruiken.
    . Ik heb geprobeerd met scanline de mask en de bitmap zelf te doorlopen om performance te verbeteren (nu doe ik het met de Pixels property) maar dat is me nog niet gelukt. Hoe ga je 8 bits naar voren? Scanline geeft een Pointer maar als je die Inc t ga je 32 lijkt me

    Edit: Reply als je wil maar op de "transparant bitmaps printen" thread over scanline
    Last edited by hbrouwer; 12-Feb-07 at 22:39.

  7. #7
    Game-Programmer nschagen's Avatar
    Join Date
    Jun 2003
    Location
    Alkmaar
    Posts
    685
    Ik zal er naar kijken (heb nu geen tijd.. want ik moet naar mn bed )

    Je kunt een pointer 8 bits (1 byte) verplaatsen door te het volgende te doen:

    Code:
    var P: Pointer;
    begin
    ...
     (PChar(Pointer)+1)^ := 255;
    ...
    end;
    Je moet dus eerst casten naar PChar en dan kun je er waarden bij optellen/aftrekken. Dan eventueel nog dereferencen als je niet met het geheugenadres wilt werken maar met de data die daar opgeslagen staat.

    Suc6
    When things don't go right, Turn left

  8. #8
    FHelpdesk.Disable; hbrouwer's Avatar
    Join Date
    Feb 2007
    Location
    Nieuwendijk
    Posts
    26
    ok, bedankt! als ik verder kom post ik dat wel in mn thread erbij.

    Heb net uitgevonden dat het mask monochrome is. TBitmap.MaskHandle is readonly dus je kan er ook niks anders inzetten. Ik denk dat je er wat anders op moet verzinnen voor alpha

    Bekijk de source van TGifImage eens, die gebruikt intern dus ook een aparte mask bitmap. In de TGifPainter paint ie dus bitmap samen met de mask. Misschien kan je iets dergelijks maken maar dan met een 8 bits mask. Ik denk dat je er meer van kan maken dan ik, want ik snap die ROPs en bitshifts nog niet helemaal

    Ik heb wel weer een nieuwe vraag.. enig idee hoe je zon monochrome bitmap met scanline doorloopt? ik wil iets doen als

    Code:
    while i < bmp.width * bmp.height do
    begin
      if maskPixel = clBlack then //hoe krijg ik 1 of 0 in maskPixel?
        Printer.Canvas.Pixels[..,..] := srcPixelColor;
    
      inc(maskPixel); //1 bit
      inc(srcPixel); //24 bits? (gif)
    
      inc(i);
    end;
    Last edited by hbrouwer; 13-Feb-07 at 00:42.

  9. #9
    Het leuke is dat een bitmap technisch gesproken wel Alpha ondersteunt, maar dat zo'n beetje niemand er gebruik van maakt. 32 bit bitmaps gebruiken namelijk nog steeds 1 byte per kleur, dus je hebt dan 1 byte over voor -je raadt het al- alpha!

    De meeste tekenprogramma's negeren dit echter en vullen de laatste byte op met nullen o.i.d., maar laatst kwam ik er toevallig achter:
    Met IconLover, de icon-editor van AhaSoft, kun je icons opslaan als bitmaps. Deze nemen dan ook deze vierde byte mee. De betreffende bitmap heb ik vervolgens gebruikt om als icoon te gebruiken voor een Office 2007 button, omdat daar geen ico voor gebruikt kan worden. En jawohl! De bitmap werd transparant. Dus ik ken in ieder geval 1 applicatie die dit alpha channel schrijft en 1 applicatie die er gebruik van maakt.

    Maar goed, om een lang verhaal nog langer te maken: Kijk eens op deze pagina. Alpha blending a bitmap.
    1+1=b

  10. #10
    Nog 3 maanden student :)
    Join Date
    Oct 2003
    Location
    Sittard
    Posts
    491
    en niet te vergeten dat een 32bit bitmap veel sneller is te verwerken doordat het altijd over dword sizes gaat

    dus je scanline kun je veel sneller gebruiken door o.a. betere alignment

  11. #11
    Game-Programmer nschagen's Avatar
    Join Date
    Jun 2003
    Location
    Alkmaar
    Posts
    685
    Ik weet dat als ik mijn TBitmap instel op pf32bit, dat ik dan een extra byte heb voor de alpha.
    Het probleem is dat als ik met de canvas routines ga tekenen, deze data verdwijnt of verprutst word.
    Een gewone TColor ondersteund geen alpha en als ik dus een lijn of rechthoek teken, worden de alpha bytes op 0 gezet.
    (Correct me if i'm wrong).

    Dit is de rede dat ik een apart 8bit bitmap wou gebruiken zodat ik de de volgende routine kon schrijven:

    Code:
    TAlphaColor = record
      r,g,b,a: byte;
    end;
    
    
    procedure DrawRect(x,y,width,height: integer; Color: TAlphaColor);
    begin
      with fBitmap.canvas do
      begin
        //stel RGB kleur in
        Brush.Color := RGB(Color.r,Color.b,Color.g);
        Pen.Color := RGB(Color.r,Color.b,Color.g);
         
        Rectangle(Bounds(x,y,width,height)); 
      end;
    
      with fAlphaMask.canvas do
      begin
        //stel Alpha waarde als kleur in 
        //weet niet hoe dit eruit gaat zien, ik maak nu een soort 24bit      
        //grijswaarde maar dat zal wel fout zijn :) 
        Brush.Color := RGB(Color.a,Color.a,Color.a);
        Pen.Color := RGB(Color.a,Color.a,Color.a);
         
        Rectangle(Bounds(x,y,width,height)); 
      end;
    end;
    Zoiets wil ik bereiken, mocht iemand geen betere workaround in gedachten hebben
    Het gaat er mij om dat ik de canvas functies op een enigsinds normale manier kan gebruiken en dat ik uiteindelijk een goede ARGB set kan creeeren voor elke pixel.

    Maar er zijn nog wat vraagtekens. Hoe maak ik een 8bit Bitmap en hoe stel ik een 8bit kleur in??
    When things don't go right, Turn left

  12. #12
    FHelpdesk.Disable; hbrouwer's Avatar
    Join Date
    Feb 2007
    Location
    Nieuwendijk
    Posts
    26
    De pixelformat kan je zelf op pf8bit zetten. Dan heb je nog een grayscale palette nodig. Na deze pagina wat te hebben doorgespit kwam ik op het volgende om zon palette te maken. Zoals je ziet, kan je dan in kleur tekenen op het canvas, daarbij wordt de kleur omgezet naar de dichtstbijzijnde waarde in het palette (volgens mij). Bij drawen van de bitmap op het scherm zie je het resultaat in grayscale...


    Code:
    //Deze function geeft een palette met grijswaarden van 0 tot 255 terug
    FUNCTION TForm1.GetGrayscalePalette: hPalette;
    VAR
      Palette: TMaxLogPalette;
      i: Integer;
    BEGIN
      Palette.palVersion := $300;
      Palette.palNumEntries := 256;
    
      for i := 0 to 255 do
      begin
        WITH Palette.palPalEntry[i] DO
        BEGIN
          peRed := i;
          peGreen := i;
          peBlue := i;
          peFlags := 0
        END;
      end;
    
      RESULT := CreatePalette(pLogPalette(@Palette)^)
    END
    
    procedure TForm1.Button2Click(Sender: TObject);
    var
      bmp: TBitmap;
    begin
    //geef me een 8 bits bitmap
      bmp := TBitmap.Create;
      bmp.PixelFormat := pf8bit;
    
    //met een grayscale palette
      bmp.Palette := GetGrayscalePalette;
    
      bmp.Width := 10;
      bmp.Height := 10;
    
    //teken 
      bmp.Canvas.Brush.Color := clRed;
      bmp.Canvas.Rectangle(0,0,10,10);
    
    //zie het resultaat
      Self.Canvas.Draw(0,0,Bmp);
    
      bmp.Free;
    end;
    Volgens mij kan je bij het tekenen ook nog wat veranderen aan het palette matchen:

    uit TColor help:

    If the highest-order byte is zero, the color obtained is the closest matching color in the system palette. If the highest-order byte is one ($01 or 0x01), the color obtained is the closest matching color in the currently realized palette. If the highest-order byte is two ($02 or 0x02), the value is matched with the nearest color in the logical palette of the current device context.
    Dat zou dan gebruikt moeten worden op het punt:
    bmp.Canvas.Brush.Color := myColor;

    Ik verzin dit ook as i go, maar dit lijkt te werken. Ook voor mij geldt correct me if im wrong :-)

    suc6..

    Edit: Hier nog wat gevonden over werken in 8 of 32 bit en grayscale. Hoe is je Duits? Graustufen is grijswaarden

    Edit2: Hoezo het wiel opnieuw uitvinden? http://rakasaka.fc2web.com/delphi/grayscale.html. Het kon ook bijna niet anders..
    tussen de blubbertekst staat delphi en die lijkt verdacht veel hierop.. daar met een colortograyscale functie.. En nog eens in TGifImage ook.. Ik leer een hoop van dat component..

    Excuseer mijn overvloed aan posts, maar toevallig ben ik ook bezig met plaatjes en in het bijzonder het printen ervan, dus ik lift hier een beetje mee als dat mag
    Last edited by hbrouwer; 15-Feb-07 at 01:46. Reason: palnumentries moest 256 zijn ipv 255

  13. #13
    Reader
    Join Date
    May 2002
    Location
    Holland
    Posts
    3,382
    Even een reactie op een antieke post: Vcl.GraphUtil.DrawTransparentBitmap() houdt rekening met het alpha channel van de pixels in een 32 bits bitmap.

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
  •