Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Image data to bitmap?!?

  1. #1

    Image data to bitmap?!?

    I am writting a games engine which uses its own image format, simply a TGA file with most of the extras taken out, just left with the size, data and some other information. But i would also like the ability to view this image in a Bitmap and use it with TOpenPictureDialog, but im not really sure where i can put the data in the bitmap?

    I read the image data using Blockread and a PChar, can i use this with scanline or something?
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  2. #2

    Image data to bitmap?!?

    Yep, you can write to a bitmap's scanlines in order to copy over stuff. First, ensure three things:

    1) Your bitmap's pixel format is set appropriately
    2) You've set its width
    3) You've set its height

    You declare a type that's a pointer to an array of whatever for your pixel type, and then a pointer to it. The "whatever" in this case is the appropriate pixel type (e.g. Longword -> 32 bit, a packed record w/ rgb for 24 bit, word for 16 bit, etc.).

    There's some sample code from another thread that you should hopefully be able to adapt: here you go
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  3. #3

    Image data to bitmap?!?

    Hmm i don't seem to be getting anything

    The format started as an uncompressed 24bit TGA file and then basic info passed to the new format.
    I have my Texture class to load the texture from file and stores the data in a header.

    the header looks like this:
    Code:
      TcxtHeader = Record
        Height,Width,BPP&#58; Cardinal;
        Format&#58; Word;
        Data&#58; PChar;
      end;
    and i try to get a bitmap from the data:
    Code:
    function TcxTexture.GetBitmap&#58; TBitmap;
    var
      wScanLine, i&#58; Integer;
    begin
      Result &#58;= TBitmap.Create;
      Result.PixelFormat &#58;= pf24bit;
      Result.Width &#58;= Header.Width;
      Result.Height &#58;= Header.Height;
      wScanLine &#58;= Header.Width*&#40;Header.BPP div 8&#41;;
      For i &#58;= 0 to Header.Height-1 Do
      Begin
        PPixelArray&#40;Result.Scanline&#91;i&#93;&#41;^&#91;0&#93; &#58;= wScanLine;
      End;
    end;
    Im guessing that i have made a really stupid mistake some where here :roll:.

    I am also using a TImage to view the extracted TBitmap, by assigning it to the Picture property.
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  4. #4

    Image data to bitmap?!?

    You're reasonably close but there are a couple of problems with your code.

    The process is as follows (note that this assumes your data is linear, i.e. no gaps between a row of pixels, so adjust it if it's not):

    Set the width, height and bpp for your bitmap appropriately
    Set the next-row-of-pixels-to-copy variable to the first source pixel
    for every scanline, copy width * (bpp div 8 ) bytes from your source tga to your destination bitmap then increase the offset by width bytes.

    Remember that the scanlines for a bitmap are just pointers -- you have to write to the memory at that address, and you have to ensure that you're writing enough info to fill up a row of pixels each time. Something like this (untested but compiles):

    [pascal]function TcxTexture.GetBitmap: TBitmap;
    var
    wScanLine, i: Integer;
    Offset: PChar; // next row of pixels to copy from source
    begin
    Result := TBitmap.Create;
    Result.PixelFormat := pf24bit;
    Result.Width := Header.Width;
    Result.Height := Header.Height;
    wScanLine := Header.Width*(Header.BPP div ;

    // start with the first pixel of the image
    Offset := Header.Data;

    for i := 0 to Header.Height-1 Do
    begin
    // copy over a row worth of pixels at a time
    Move(Offset^, PPixelArray(Result.Scanline[ i ])^[0], wScanline);

    // move a row of pixels further for next time
    Inc(offset, wScanline);
    end;
    end;[/pascal]

    Notice that I'm using Move here -- this will copy n bytes of data from one place to another (in this case, copying over your image data onto the newly created bitmap).

    As a side note, it's better style to create and destroy classes (or allocate memory) in the same scope. The above function creates a bitmap, but the caller must free it. This is pretty bad news in terms of exception handling and call lead to jumping through hoops if you want to be safe. I'd recommend passing in a bitmap and having the GetBitmap function thing just using it, without allocating things for itself. This not only clears up the code (it's much easier to track where objects are created and freed) but it gives more intuitive exception handling. E.g.

    [pascal]procedure TcxTexture.GetBitmap(UseMe: TBitmap);
    var
    // vars here
    begin
    Bmp.PixelFormat := pf24Bit;
    Bmp.Width := Header.Width;
    //etc
    end;

    // and later on in your code

    procedure TcxTexture.Whatever;
    var
    Bmp: TBitmap;
    begin
    Bmp := TBitmap.Create;
    try
    GetBitmap(Bmp);
    // do stuff
    finally
    Bmp.Free;
    end;
    end;[/pascal]
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  5. #5

    Image data to bitmap?!?

    Hmm im still not getting anything back, im sure im doing something stupid. Im thinking when im loading the texture at the beginning im not copying the data correctly?!? im not sure.

    heres a copy of the project and files, could you possibly have a look to see where im going wrong .

    http://www.biocoders.org/files/Quick.zip

    its about 332kb

    The TcxTexture is a class which im using in my Games engine, I just need this bit so i can view the texture in the editors im building.
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  6. #6

    Image data to bitmap?!?

    I belive that you can't save/load a PChar so you should try to change
    [pascal]TcxtHeader = Record
    Height,Width,BPP: Cardinal;
    Format: Word;
    Data: PChar;
    end; [/pascal]
    to
    [pascal]TcxtHeader = Record
    Height,Width,BPP: Cardinal;
    Format: Word;
    Data: String;
    end; [/pascal]
    Signature:
    <br />This is a block of text that can be added to posts you make. There is a 255 character limit

  7. #7

    Image data to bitmap?!?

    I use PChar to store the data in the loading procedure of the texture, TcxtHeader is just being used to store the data incase i need it, like in the GetBitmap function.

    I know that the texture is being saved and loaded correctly in the class because it works fine in OpenGL.

    But im not sure if i am using it properly.. When the texture is loaded at the end when i set the TcxtHeader information i just use
    [pascal]
    Header.Data := Data;
    [/pascal]
    Them both being PChar's.

    When i view the texture using TImage all i get is a plain white rectangle the size of the texture, but with well no texture :?
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

  8. #8

    Image data to bitmap?!?

    [quote="M109uk"]I use PChar to store the data in the loading procedure
    But im not sure if i am using it properly.. When the texture is loaded at the end when i set the TcxtHeader information i just use
    [pascal]
    Header.Data := Data;
    [/pascal]
    Them both being PChar's.

    Nope, is not correct, Pchar assigment is used as null terminated string, mean that it will copy the "string" pointed until any byte zero is found.

    use Move command for copy the whole block data from one pointer to another, you have to tell your data size.


    tp.

  9. #9

    Image data to bitmap?!?

    I've finally got around to taking a look at your code. Some things I spotted that may cause problems:

    First of all, bpp in my example stood for "bits per pixel", hence you needed to divide by 8. However, your code uses "bytes per pixel", so you don't want to be dividing by 8 in the GetBitmap function.

    Secondly, and most importantly, you're freeing the data pointer at the end of the LoadTexture function so the header's data pointer will then point to freed memory.

    I'll take another look some time tonight or tomorrow. Sorry about the delay!
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  10. #10

    Image data to bitmap?!?

    First of all, bpp in my example stood for "bits per pixel", hence you needed to divide by 8. However, your code uses "bytes per pixel", so you don't want to be dividing by 8 in the GetBitmap function.
    Yeah i thought that might of been a problem, i tried to use the same math i did when writing the image: Width*Height*BPP in the GetBitmap function, but that just came up with errors

    Secondly, and most importantly, you're freeing the data pointer at the end of the LoadTexture function so the header's data pointer will then point to freed memory.
    ops:, i knew it was something stupid :roll:

    I'll take another look some time tonight or tomorrow. Sorry about the delay!
    Thanks that would be great
    M109uk
    <br />--------------------------------------------------------
    <br />www.pulse-soft.oneuk.com

Page 1 of 2 12 LastLast

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
  •