Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 9 of 9 total
Thread Graphics problem with DBISAM only slightly involved
Thu, Sep 20 2007 8:20 PMPermanent Link

"Jeff Cook"
Kia Orana

The code below is my attempt to post the contents of a TImage to a blob
field in DBISAM 3.30.  DBISAM is not involved with the problem itself.

What is happening is that I'm using a TImage and apparently
successfully cropping and rotating photos.  The photos appear cropped
and rotated on the screen.  Then I go to save them back into the
database and it comes unglued.

As I say, the TImage is displaying the results of my editing, but when
I save, the original unedited image is saved.  My debugging lines that
are used to save the images before posting to the DBISAM table prove
that DBISAM isn't involved as the .jpg and .bmp files show the original
uncropped and unrotated image - not what is on screen.

Any one any idea what might be happening?

Cheers

Jeff
=======================================================================
procedure TEditImageForm.PostPhoto;
const
 ThumbHeight: integer = 50;
var
 oJPG: TJPEGImage;
 oBmp: TBitmap;
 Stream: TMemoryStream;
begin
 oJPG := TJPEGImage.Create;
 oBmp := TBitmap.Create;
 Stream := TMemoryStream.Create;
 try
   Image1.Picture.SaveToFile('C:\temp\photos\tavita.bmp');
   oJPG.Assign(Image1.Picture.Bitmap);
   oJPG.Compress;
   Stream.Clear;
   oJPG.SaveToStream(Stream);
   oJPG.SaveToFile('C:\temp\photos\tavita.jpg');
   Stream.Position := 0;
   PhotoFormNew.tblPhotosImage.LoadFromStream(Stream);
   oBmp.Width := (oJPG.Width * ThumbHeight) div oJPG.Height;
   oBmp.Height := ThumbHeight;
   oBmp.Canvas.StretchDraw(Rect(0, 0, oBmp.Width - 1, oBmp.Height -
1), oJPG);
   oJPG.Assign(oBmp);
   oJPG.Compress;
   Stream.Clear;
   Stream.Position := 0;
   oJPG.SaveToStream(Stream);
   oJPG.SaveToFile('C:\temp\photos\tavita-thumb.jpg');
   Stream.Position := 0;
   PhotoFormNew.tblPhotosThumbNail.LoadFromStream(Stream);
 finally
   oBmp.Free;
   oJPG.Free;
   Stream.Free;
 end;
end;

--
Jeff Cook
Aspect Systems Ltd
www.aspect.co.nz
+
Joan and Jeff Cook
The Cooks Oasis
www.cookislandsoasis.com
Sat, Sep 22 2007 12:43 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Jeff,

<< Any one any idea what might be happening? >>

oBmp.Canvas.StretchDraw(Rect(0, 0, oBmp.Width - 1, oBmp.Height -1), oJPG);

What does the bitmap look like after this line, if saved to a file ?

--
Tim Young
Elevate Software
www.elevatesoft.com

Mon, Sep 24 2007 4:28 PMPermanent Link

"Jeff Cook"
Tim Young [Elevate Software] wrote:

> Jeff,
>
> << Any one any idea what might be happening? >>
>
> oBmp.Canvas.StretchDraw(Rect(0, 0, oBmp.Width - 1, oBmp.Height -1),
> oJPG);
>
> What does the bitmap look like after this line, if saved to a file ?

Hi Tim thanks for your reply.

   oBmp.Canvas.StretchDraw(Rect(0, 0, oBmp.Width - 1, oBmp.Height -
1), oJPG);
   oBmp.SaveToFile('C:\temp\photos\tavita for tim.bmp'); <<<<<<<
   oJPG.Assign(oBmp);
   oJPG.Compress;
   Stream.Clear;
   Stream.Position := 0;
   oJPG.SaveToStream(Stream);
   oJPG.SaveToFile('C:\temp\photos\tavita-thumb.jpg');

I added the line as suggested and the files "tavita for tim.bmp" and
"tavita-thumb.jpg" look identical - the unrotated, uncropped versions
of the original file, reduced to a thumbnail size.

Cheers

Jeff

P.S.  Sorry for the delay in answering - I live on a beautiful tropical
island and decided this weekend to stop and take advantage of it.

--
Jeff Cook
Aspect Systems Ltd
www.aspect.co.nz
+
Joan and Jeff Cook
The Cooks Oasis
www.cookislandsoasis.com
Mon, Sep 24 2007 6:33 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Jeff,

<< I added the line as suggested and the files "tavita for tim.bmp" and
"tavita-thumb.jpg" look identical - the unrotated, uncropped versions of the
original file, reduced to a thumbnail size. >>

Okay, I mis-read your post.  I thought the issue was the thumbnail, when the
issue is the cropping and rotating.  How are you cropping and rotating the
original image ?

--
Tim Young
Elevate Software
www.elevatesoft.com

Mon, Sep 24 2007 8:35 PMPermanent Link

"Jeff Cook"
Tim Young [Elevate Software] wrote:

> Jeff,
>
> << I added the line as suggested and the files "tavita for tim.bmp"
> and "tavita-thumb.jpg" look identical - the unrotated, uncropped
> versions of the original file, reduced to a thumbnail size. >>
>
> Okay, I mis-read your post.  I thought the issue was the thumbnail,
> when the issue is the cropping and rotating.  How are you cropping
> and rotating the original image ?

With some cunning code that I got from the web!

The code is pasted below my sig.

I don't pretend to know how it all works, but it does as far as the
visible image is concerned.

--
Jeff Cook
Aspect Systems Ltd
www.aspect.co.nz
+
Joan and Jeff Cook
The Cooks Oasis
www.cookislandsoasis.com

procedure TEditImageForm.btnAntiClockwiseClick(Sender: TObject);
var
 lRadians: real;
 DC: longint;
 H, W: integer;
 Degrees: integer;
begin
 try
   Screen.Cursor := crHourGlass;
   EraseRect; // deletes the rubberband rectangle if it exists
   if (Sender as TButton).Name = 'btnClockwise' then
     Degrees := 90
   else Degrees := -90;
   lRadians := PI * Degrees / 180;
   DC := Image1.Picture.Bitmap.Canvas.Handle;
   H := Image1.Picture.Bitmap.Height;
   W := Image1.Picture.Bitmap.Width;
   RotateBitmap(DC, W, H, lRadians);
   Image1.Width := W;
   Image1.Height := H;
   Image1.Picture.Bitmap.Width := W;
   Image1.Picture.Bitmap.Height := H;
   BitBlt(Image1.Picture.Bitmap.Canvas.Handle, 0, 0, W, H, DC, 0, 0,
SRCCopy);
   Image1.Refresh;
 finally
   Screen.Cursor := crDefault;
 end;
end;

procedure RotateBitmap(var hBitmapDC: Longint; var lWidth: Longint;
 var lHeight: Longint; lRadians: real);
var
 I: Longint; // loop counter
 J: Longint; // loop counter
 hNewBitmapDC: Longint; // DC of the new bitmap
 hNewBitmap: Longint; // handle to the new bitmap
 lSine: extended; // sine used in rotation
 lCosine: extended; // cosine used in rotation
 X1: Longint; // used in calculating new
                                   //   bitmap dimensions
 X2: Longint; // used in calculating new
                                   //     bitmap dimensions
 X3: Longint; // used in calculating new
                                   //     bitmap dimensions
 Y1: Longint; // used in calculating new
                                   // bitmap dimensions
 Y2: Longint; // used in calculating new
                                   // bitmap dimensions
 Y3: Longint; // used in calculating new
                                   // bitmap dimensions
 lMinX: Longint; // used in calculating new
                                   // bitmap dimensions
 lMaxX: Longint; // used in calculating new
                                   // bitmap dimensions
 lMinY: Longint; // used in calculating new
                                   // bitmap dimensions
 lMaxY: Longint; // used in calculating new
                                   // bitmap dimensions
 lNewWidth: Longint; // width of new bitmap
 lNewHeight: Longint; // height of new bitmap
 lSourceX: Longint; // x pixel coord we are blitting
                                   // from the source  image
 lSourceY: Longint; // y pixel coord we are blitting
                                   // from the source image
begin
        // create a compatible DC from the one just brought
        // into this function
 hNewBitmapDC := CreateCompatibleDC(hBitmapDC);
        // compute the sine/cosinse of the radians used to
        // rotate this image
 lSine := Sin(lRadians);
 lCosine := Cos(lRadians);
        // compute the size of the new bitmap being created
 X1 := Round(-lHeight * lSine);
 Y1 := Round(lHeight * lCosine);
 X2 := Round(lWidth * lCosine - lHeight * lSine);
 Y2 := Round(lHeight * lCosine + lWidth * lSine);
 X3 := Round(lWidth * lCosine);
 Y3 := Round(lWidth * lSine);
       // figure out the max/min size of the new bitmap
 lMinX := Min(0, Min(X1, Min(X2, X3)));
 lMinY := Min(0, Min(Y1, Min(Y2, Y3)));
 lMaxX := Max(X1, Max(X2, X3));
 lMaxY := Max(Y1, Max(Y2, Y3));
        // set the new bitmap width/height
 lNewWidth := lMaxX - lMinX;
 lNewHeight := lMaxY - lMinY;
        // create a new bitmap based upon the new width/height of the
        // rotated bitmap
 hNewBitmap := CreateCompatibleBitmap(hBitmapDC, lNewWidth,
lNewHeight);

        //attach the new bitmap to the new device context created
        //above before constructing the rotated bitmap
 SelectObject(hNewBitmapDC, hNewBitmap);
        // loop through and translate each pixel to its new location.
        // this is using a standard rotation algorithm
 for I := 0 to lNewHeight do begin
   for J := 0 to lNewWidth do begin
     lSourceX := Round((J + lMinX) * lCosine + (I + lMinY) * lSine);
     lSourceY := Round((I + lMinY) * lCosine - (J + lMinX) * lSine);
     if (lSourceX >= 0) and (lSourceX <= lWidth) and
       (lSourceY >= 0) and (lSourceY <= lHeight) then
       BitBlt(hNewBitmapDC, J, I, 1, 1, hBitmapDC,
         lSourceX, lSourceY, SRCCOPY);
   end;
 end;
        // reset the new bitmap width and height
 lWidth := lNewWidth;
 lHeight := lNewHeight;
        // return the DC to the new bitmap
 hBitmapDC := hNewBitmapDC;
        // destroy the bitmap created
 DeleteObject(hNewBitmap);
end;

procedure TEditImageForm.EraseRect;
begin
 if bRect then
 begin
   SetRect(fRect, iLeft, iTop, iRight, iBottom);
   Image1.Canvas.DrawFocusrect(fRect);
 end;
 bRect := False;
end;

procedure TEditImageForm.btnCropClick(Sender: TObject);
var
 wbmp: TBitMap;
begin
 if not bRect then
   MessageDlg('Select an area before you crop!', mtError, [mbOK], 0)
 else begin
   EraseRect;
   wbmp := TBitMap.Create;
   try
     Image1.Canvas.draw(-iLeft, -iTop, Image1.Picture.Bitmap);
     Image1.Picture.Bitmap.Width := iRight - iLeft;
     Image1.Picture.Bitmap.Height := iBottom - iTop;
     wbmp.Width := (Image1.Picture.Bitmap.Width * iHeight)
       div Image1.Picture.Bitmap.Height;
     wbmp.Height := iHeight;
     wbmp.Canvas.StretchDraw(Rect(0, 0, wbmp.Width - 1, wbmp.Height -
1),
       Image1.Picture.Bitmap);
     Image1.Picture.Bitmap.Assign(wbmp);
   finally
     wbmp.Free;
   end;
 end;
end;
Tue, Sep 25 2007 5:30 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Jeff,

<< With some cunning code that I got from the web!

The code is pasted below my sig.

I don't pretend to know how it all works, but it does as far as the visible
image is concerned. >>

Hmm, weird.  And this code is all run prior to your PostPhoto routine ?

--
Tim Young
Elevate Software
www.elevatesoft.com

Tue, Sep 25 2007 8:05 PMPermanent Link

"Jeff Cook"
Tim Young [Elevate Software] wrote:

>
> Hmm, weird.  And this code is all run prior to your PostPhoto routine
> ?

Tim

Yes.

I have a query and a datasource.  The DataChange event of the
datasource has code:-

procedure TEditImageForm.dsImageDataChange(Sender: TObject; Field:
TField);
begin
 if Field = nil then
 begin
   ShowImage;
 end;
end;

.... where ShowImage locates the record in the table and displays it on
a TImage.

I do the cropping and rotating in response to buttons, then do the
posting on ticking the tick on a navigator like this:-

procedure TEditImageForm.navImageClick(Sender: TObject;
 Button: TNavigateBtn);
begin
 if Button = nbEdit then
 begin
   Image1.ShowHint := True; // hint for mouse actions to crop
   pnlEdit.Enabled := True; // enable the panel of crop and rotate
buttons
 end
 else begin
   Image1.ShowHint := False;
   pnlEdit.Enabled := False;
   if Button = nbPost then
   begin
     PhotoFormNew.tblPhotos.Edit;
     PostPhoto;
     PhotoFormNew.tblPhotos.Post;

PhotoFormNew.tblPhotosImage.SaveToFile('c:\temp\photos\tavita1.jpg');
// another debug!
     ModalResult := mrOK;
   end;
 end;
end;

--
Jeff Cook
Aspect Systems Ltd
www.aspect.co.nz
+
Joan and Jeff Cook
The Cooks Oasis
www.cookislandsoasis.com
Thu, Sep 27 2007 11:36 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Jeff,

<< I have a query and a datasource.  The DataChange event of the datasource
has code:-

procedure TEditImageForm.dsImageDataChange(Sender: TObject; Field:
TField);
begin
 if Field = nil then
 begin
   ShowImage;
 end;
end;

... where ShowImage locates the record in the table and displays it on a
TImage. >>

What happens if you disable this ?  It may be that the image is getting
reset through this event handler.

--
Tim Young
Elevate Software
www.elevatesoft.com

Thu, Sep 27 2007 4:57 PMPermanent Link

"Jeff Cook"
Tim Young [Elevate Software] wrote:

> Jeff,
>
> << I have a query and a datasource.  The DataChange event of the
> datasource has code:-
>
> procedure TEditImageForm.dsImageDataChange(Sender: TObject; Field:
> TField);
> begin
>  if Field = nil then
>  begin
>    ShowImage;
>  end;
> end;
>
> ... where ShowImage locates the record in the table and displays it
> on a TImage. >>
>
> What happens if you disable this ?  It may be that the image is
> getting reset through this event handler.


Thanks Tim, that's exactly what is happening!

Now I need to write some cunning code to avoid the problem.

Thanks a heap

Jeff

--
Jeff Cook
Aspect Systems Ltd
www.aspect.co.nz
+
Joan and Jeff Cook
The Cooks Oasis
www.cookislandsoasis.com
Image