Recent

Author Topic: Works on Win32 but not on WinCE.  (Read 9534 times)

dan59314

  • New Member
  • *
  • Posts: 38
Works on Win32 but not on WinCE.
« on: October 06, 2009, 06:57:22 am »
Hi,

   I am trying to get equivalnet of TBitmap.Scanline[0] by using TLazIntfImage,
   and draw FBmp1 on FBmp2 in a specified scale within FRasView record.
   
   The following code works fine on Win32, But has problem on WinCE.
   
   Win32 Shows the correct image http://dan59314.myweb.hinet.net/Image2.jpg
   
   
   In WinCE,
   
      When I load a pf8Bit *.bmp file and paint, programe didn't halt, but The result is incorrect http://dan59314.myweb.hinet.net/Image1.jpg
   
   
      When I load a pf24Bit *.bmp file and paint, programe halt and exit while calling RastPainter.PaintRGB24(),
      not even enter the function RastPainter.PaintRGB24().
      
   
   Can anyone tell me what's going wrong with WinCE coding....
   
   
Code: [Select]
FBmp1, FBmp2 are TBitmap, have data, not empty
......

var
  FLazImage1, FLazImage2 : TLazIntfImage;  // Create and Free in FormCreate() and FormDestroy()

......

Paintfunction bellow........
 
  try
   FLazImage1.LoadFromBitmap(FBmp1.Handle,FBmp1.MaskHandle);
   FLazImage2.LoadFromBitmap(FBmp2.Handle,FBmp2.MaskHandle);             
 
 
   case FBmp1.PixelFormat of
   pf8Bit:
     begin
       strideBytes1 := RastPainter.BytesPerScanline(FBmp1.Width, 8, 32);
  strideBytes2 := RastPainter.BytesPerScanline(FBmp2.Width, 8, 32);

  FBmp1Scan0 := Pointer(FLazCnvImage.PixelData);
  FBmp2Scan0 := Pointer(FLazImage.PixelData);
       // this function paint FBmp1Scan0 into FBmp2Scan0 ----------------------
       RastPainter.PaintRGB8(FRasView, FBmp2Scan0, strideBytes2, FBmp2.Width, FBmp2.Height,
            FBmp1Scan0, strideBytes1, FBmp1.Width, FBmp1.Height, true);     
     end;   
   pf24Bit:
     begin
       strideBytes1 := RastPainter.BytesPerScanline(FBmp1.Width, 24, 32);
  strideBytes2 := RastPainter.BytesPerScanline(FBmp2.Width, 24, 32);

  FBmp1Scan0 := Pointer(FLazCnvImage.PixelData);
  FBmp2Scan0 := Pointer(FLazImage.PixelData);
       // this function paint FBmp1Scan0 into FBmp2Scan0 ----------------------
       RastPainter.PaintRGB24(FRasView, FBmp2Scan0, strideBytes2, FBmp2.Width, FBmp2.Height,
            FBmp1Scan0, strideBytes1, FBmp1.Width, FBmp1.Height, true);     
     end;     
   end;
           
  finally
 
  FBmp2.LoadFromIntfImage(FLazCnvImage);
  end;
 
   
   
   
 
           
  // RastPainter.PaintRGB24(const aView:TRastViewRec;
  //    const CnvScan0:Pointer; cnvstrideBytes:integer; CnvWidth, CnvHeight:integer;
  //    Const ImgScan0:Pointer; ImgstrideBytes:integer; ImgWidth, ImgHeight:integer;
  //    blDIBUpWard:LongBool=true); 
  //
« Last Edit: October 08, 2009, 03:18:59 am by dan59314 »

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2496
Re: Works on Win32 but not on WinCE.
« Reply #1 on: October 06, 2009, 11:41:45 am »
in you example you have FLazImage1 and FLazImage2, but when accessing the data you use FLazImage
Code: [Select]
FBmp2Scan0 := Pointer(FLazImage.PixelData);
BTW, you don't need to get the LazImage data through LoadFromBitmap anymore (using LoadFromBitmap results in an image in pfDevice depth and might loose alpha info).
TBitmap (or any descendant of TRaserImage) has a RawImage: TRawImage property. Here you have directly access to the pixel data.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

dan59314

  • New Member
  • *
  • Posts: 38
Re: Works on Win32 but not on WinCE.
« Reply #2 on: October 07, 2009, 03:43:18 am »
TBitmap (or any descendant of TRaserImage) has a RawImage: TRawImage property. Here you have directly access to the pixel data.

Hi, Marc,

  Thanks for the reply.

In Win32,

  Yes, I did use TBitmap.RawImage originally,  I can mostly paint from FBmp1 to FBmp2 without problem, but sometimes it didn't paint. Don't know why?

  Also I need to draw FBmp2 to TPaintBox. If I use TLazIntfImage -> FBmp2, I can use BitBlt(PaintBox1.Canvas.Handle, 0,0, FBmp2.Width, FBmp2.Height, FBmp2.Canvas.Handle, 0,0 srcCopy) to show FBmp2 on TPaintbox without problem.  But never success if I use FBmp2.RawImage.


   Briefly,

   1.  With FBmp1.RawImage, FBmp2.RawImage, I can mostly draw FBmp1 on FBmp2, but not all the time.

   2.  I can't draw FBmp2 on TPaintBox by using
     BitBlt(PaintBox1.Canvas.Handle, 0,0,FBmp2.Width, FBmp2.Height, FBmp2.Handle,0,0,SrcCopy);

     neither   PaintBox1.Canvas.Draw(0,0, FBmp2); 

In WinCE,
   So far, never successed.


Daniel
« Last Edit: October 07, 2009, 03:47:26 am by dan59314 »

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2496
Re: Works on Win32 but not on WinCE.
« Reply #3 on: October 07, 2009, 12:31:50 pm »
Did you use the Begin/EndUpdate when modifying the rawimage data ?
Did you check the "pixelformat" of the rawimage on CE ?
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

dan59314

  • New Member
  • *
  • Posts: 38
Re: Works on Win32 but not on WinCE.
« Reply #4 on: October 08, 2009, 03:14:39 am »
Did you use the Begin/EndUpdate when modifying the rawimage data ?
Did you check the "pixelformat" of the rawimage on CE ?

I tried BeginUpdate(true)  and EndUpdate(true), but nothing changed, can't BitBlt() FBmp2 on TPaintBox, either Win32 or WinCE.

Might somewhere I missed, I will tried them again. May you post souce code how to use them?
And the pixelformat? Is there any limitation for WinCE?

Acutally I worked it out both on Win32 and WinCE in another way, but the efficiency is not good.

I found if I assign FBmp2.Width with different value everytime before painting. It will works to BitBlt() FBmp2 on TPaintBox.

Then I traced into the TPaintBox.SetWidth(), It seems to free data and re-allocate memory again.

I guess that's why the efficiency is worse. If so, is there any way that I can do?


Thanks again,

Regards,

Daniel
« Last Edit: October 08, 2009, 03:33:29 am by dan59314 »

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2496
Re: Works on Win32 but not on WinCE.
« Reply #5 on: October 08, 2009, 11:45:39 am »
Did you use EndUpdate before using BitBlt ? If so then I might have missed something. In theore the handle should be recreated after EndUpdate.

The number of imageformats supported on WinCE is limited. In most cases this means that pfDevice on windows has a different depth then on CE. The rawimage.Description.Depth should reflect that.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

dan59314

  • New Member
  • *
  • Posts: 38
Re: Works on Win32 but not on WinCE.
« Reply #6 on: October 09, 2009, 02:21:03 am »
Did you use EndUpdate before using BitBlt ?


I tried EndUpdate both before BitBlt() and after BitBlt(), the same, see no FBmp2 on PaintBox1.

I already simplify the code as following, test both GDI way and RawImage way to draw a white line on FBmp2, then BitBlt() to TPaintBox. You can put a TPaintBox on Form and try.

GDI way just work fine, but the RawImage way.

In RawImage way, to assure that I do draw white line on FBmp2, I save it to a file and check it without missing, just can't BitBlt() FBmp2 to Paintbox1.

The RawImage way only works if I change the FBmp2 size everytime before RawImage painting.


Thanks,

Daniel


Code: [Select]
{$DEFINE UseRawImage}

procedure TForm1.PaintBox1Paint(Sender: TObject);
type
  PRGB24 = ^TRGB24;
  TRGB24 = record
    B,G,R:byte;   
  end;                                                   
var
  BitsPerPixel, strideBytes2:integer;
  ptr2:Pointer;
  i,j:integer;
begin

  if (FBmp2.Width<>PaintBox1.Width) then FBmp2.Width := PaintBox1.Width;
  if (FBmp2.Height<>PaintBox1.Height) then FBmp2.Height := PaintBox1.Height;

  FBmp2.BeginUpdate(false);
try
  FBmp2.PixelFormat := pf24bit;
  BitsPerPixel:=24;

  // Fill PaintBox with clBlue
  with FBmp2.Canvas do
  begin
    Brush.Color := clBlue;
    Rectangle(0,0,FBmp2.Width-1, FBmp2.Height-1);
  end;


  // Draw a 5 pixel white line on y=0 of FBmp2 ---------------------------
  {$IFDEF UseRawImage}

    // Works for BitBlt() Only if the FBmp2 Size changed everytime before RawImage painting-----------------
    {if (FBmp2.Width = PaintBox1.Width) then  FBmp2.Width := PaintBox1.Width+1
    else FBmp2.Width := PaintBox1.Width;} // Change Width to resize the FBmp2

    ptr2 := FBmp2.RawImage.Data;
    strideBytes2 := RastPainter.BytesPerScanline(FBmp2.Width, BitsPerPixel, 32);

    for j:=0 to 5 do
    for i:=0 to FBmp2.Width-1 do
    begin
      pRGB24( ptr2)^.R := 255;
      pRGB24( ptr2)^.G := 255;
      pRGB24( ptr2)^.B := 255;

      ptr2 := Pointer( integer(ptr2)+3);
    end;

  {$ELSE}
    with FBmp2.Canvas do
    begin
      Pen.Width:= 5;
      Pen.Color := clWhite;
      MoveTo(0,0); LineTo(FBmp2.Width-1, 0);
    end;
  {$ENDIF}

finally
  FBmp2.EndUpdate;

  // check if white line drawed on FBmp2? ------> {$UseRawImage} --> Yes,  {$ELSE} --> Yes
  FBmp2.SaveToFile('c:\FBmp2.bmp');

  // BitBlt() gBmp to PaintBox1 ? ------->  {$UseRawImage} --> No,  {$ELSE} --> Yes
  BitBlt(PaintBox1.Canvas.Handle, 0,0,PaintBox1.Width, PaintBox1.Height, FBmp2.Canvas.Handle, 0,0,srcCopy);
end;

end;     

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2496
Re: Works on Win32 but not on WinCE.
« Reply #7 on: October 09, 2009, 11:05:30 am »
When I've some time this weekend, i'll give it a try. I hope I wont forget, but you can always bug me a IRC
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

dan59314

  • New Member
  • *
  • Posts: 38
Re: Works on Win32 but not on WinCE.
« Reply #8 on: October 09, 2009, 11:34:34 am »
Ok, thanks a lot.