TFPMemoryImage assigned to TImage.Picture don't displaying lazarus / 39-Graphics ---------------------------------------------------------------------- Awkward · 2021-09-09 21:35 I use next function to show picture file from memory. It can work for JPG or PNG but not DDS. if i will uncomment "SaveToFile" line, i will get proper PNG file. but impgPreview (TImage control) after assigning still empty. What i doing wrong? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TRGGUIForm.PreviewImage(const aname:string);var  limg:TFPMemoryImage;  lstr:TMemoryStream;  lfpc:TFPColor;  ldata:PByte;  lidx,y,x,lsize,lheight,lwidth:integer;begin  if ExtractFileExt(aname)='.DDS' then  begin    LoadDDSImage(FUData,MemSize(FUData),ldata,lwidth,lheight);     limg:=TFPMemoryImage.Create(lwidth,lheight);    lidx:=0;    for y:=0 to lheight-1 do    begin      for x:=0 to lwidth-1 do      begin      lfpc.Red  :=ldata[lidx+0] shl 8;        lfpc.Green:=ldata[lidx+1] shl 8;        lfpc.Blue :=ldata[lidx+2] shl 8;        lfpc.Alpha:=ldata[lidx+3];        limg.Colors[x,y]:=lfpc;        inc(lidx,4);      end;    end;    FreeMem(ldata);{  if i will use next 2 lines, picture displaying    limg.SaveToFile('d:\112.png');    imgPreview.Picture.LoadFromFile('d:\112.png');}    imgPreview.Picture.Assign(limg);    limg.Free;  end  else  begin    lstr:=TMemoryStream.Create();    try      lstr.SetBuffer(FUData);    imgPreview.Picture.LoadFromStream(lstr);    finally      lstr.Free;  end;  end;  imgPreview.Visible:=true;end; ---------------------------------------------------------------------- Remy Lebeau · 2021-09-09 22:11 Quote from: Awkward on September 09, 2021, 11:35:07 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {  if i will use next 2 lines, picture displaying    limg.SaveToFile('d:\112.png');    imgPreview.Picture.LoadFromFile('d:\112.png');} Have you tried using limg.SaveToStream() followed by imgPreview.Picture.LoadFromStream()?  You should not need to use a temp file at all, but you do need to still pick an image format (JPG, PNG, etc) for the TFPMemoryImage data to be converted to for display. Try this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TRGGUIForm.PreviewImage(const aName: string);var  limg: TFPMemoryImage;  lstr: TMemoryStream;  lfpc: TFPColor;  ldata: PByte;  lidx, y, x, lsize, lheight, lwidth: Integer;  lwriter: TFPWriterPNG;begin  if ExtractFileExt(aName) = '.DDS' then  begin    LoadDDSImage(FUData, MemSize(FUData), ldata, lwidth, lheight);    try      limg := TFPMemoryImage.Create(lwidth, lheight);      try        lidx := 0;        for y := 0 to lheight-1 do        begin          for x := 0 to lwidth-1 do          begin            lfpc.Red := ldata[lidx+0] shl 8;            lfpc.Green := ldata[lidx+1] shl 8;          lfpc.Blue := ldata[lidx+2] shl 8;            lfpc.Alpha := ldata[lidx+3];            limg.Colors[x, y] := lfpc;            Inc(lidx, 4);          end;        end;        FreeMem(ldata);        ldata := nil;        lstr := TMemoryStream.Create;        try        lwriter := TFPWriterPNG.Create;          try            limg.SaveToStream(lstr, lwriter);            // or: lwriter.ImageWrite(lstr, limg);          finally            lwriter.Free;          end;          lstr.Position := 0;          imgPreview.Picture.LoadFromStream(lstr);        finally          lstr.Free;        end;      finally        limg.Free;      end;    finally      if ldata <> nil then        FreeMem(ldata);    end;  end  else  begin    lstr := TMemoryStream.Create;    try      lstr.SetBuffer(FUData);      imgPreview.Picture.LoadFromStream(lstr);    finally      lstr.Free;    end;  end;  imgPreview.Visible := true;end; ---------------------------------------------------------------------- Awkward · 2021-09-10 06:23 i know this method, didn't tried it (and i think, it will work). But i wandered and want to know, why direct assign don't work. ---------------------------------------------------------------------- wp · 2021-09-10 09:05 Not 100% sure, but AFAIK TFPMemoryImage only provides a buffer for the image, but no information how the data in the buffer will have to be organized in the destination image format. I'd use a TLazIntfImage instead which provides a simpler interface to the classes of the graphics units. A png image, for example, can loaded from a LazIntfImage and thus set its required memory layout. Untested: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  IntfGraphics, fpimage; procedure TForm1.Button1Click(Sender: TObject);var  img: TLazIntfImage;  png: TCustomBitmap;  lHeight, lWidth: Integer;  lData: PByte;begin  LoadDDSImage(FUData, MemSize(FUData), ldata, lwidth, lheight);  try    png := TPortableNetworkgraphic.Create; // or TJpegImage.Create, or TBitmap.Create, or ...    try      png.SetSize(lWidth, lHeight);      png.PixelFormat := pf32bit;      img := png.CreateIntfImage;      try        for y := 0 to lheight-1 do        begin          for x := 0 to lwidth-1 do          begin            lfpc.Red := ldata[lidx+0] shl 8;            lfpc.Green := ldata[lidx+1] shl 8;            lfpc.Blue := ldata[lidx+2] shl 8;            lfpc.Alpha := ldata[lidx+3];          limg.Colors[x, y] := lfpc;            Inc(lidx, 4);          end;        end;        png.LoadFromIntfImage(img);        imgPreview.Picture.Assign(png);      finally        img.Free;      end;    finally      png.Free;    end;  finally    FreeMem(lData);  end;end; ---------------------------------------------------------------------- Awkward · 2021-09-11 16:25 Quote from: wp on September 10, 2021, 11:05:20 amNot 100% sure, but AFAIK TFPMemoryImage only provides a buffer for the image, but no information how the data in the buffer will have to be organized in the destination image format. I'd use a TLazIntfImage instead which provides a simpler interface to the classes of the graphics units. A png image, for example, can loaded from a LazIntfImage and thus set its required memory layout. you forgot to rename "limg" to "img" at one place and initialize "lidx" by 0 at another. well, picture displayed but on plack background (like no alpha) ---------------------------------------------------------------------- wp · 2021-09-11 17:57 Since I don't have neither your LoadDDSImage procedure nor a DDS image for testing, I simulated the procedure by the Lazarus paw which is read into a png, and I use the IntfImage to color the black paw in red and replace the alpha-channel by a gradient from fully transparent at the left to fully opaque white at the right. Look at the attached demo. It works as expected. If this basic code does not work in your example you should check whether the color and alpha channels are handled correctly. FPImage uses 16-bit colors and alpha. This is why you shl the rgb value by 8 bits. But you do not shl the alpha channel. I do not know if this explains why your image background is black.