I am trying to combine the RotationLayer with a regular TBitmapLayer in order to be able to use an ImgView32 layer for all it can be.
So my thoughts were:
- I have a TBitmapLayer (I need it to be BitmapLayer because I am doing with it more than just rotating). It is loaded with a BMP image
- I place a TGaugeBar on my form (just like the ones from the GR32 examples)
- When there is a mouse down on that Gauge, I start doing my computations: I create a RotationLayer where I place the contents of the original BitmapLayer.Bitmap
- OnChange of the Gauge, I use the RotLayer object created in MouseDown and give it an angle, and assign the Selection as TBitmap, the RotLayer.Bitmap
- On MouseUp I free the temporary RotationLayer object used
So basically: move the image from the actual layer to a temporary rotation layer, do the rotating there, then, when done, move the rotated image back to the BitmapLayer...
So in the end, my logic seems to work, except that I need to do the actual rotation on the BitmapLayer manually using a function provided in another SO question (link bellow). Because it appears that the rotationLayer does not actually rotate the image inside it's Bitmap. It only seems to display it rotated...
Now my problems are:
- I need to be able to 'resize' the original TBitmapLayer so it wont crop the rotated image to fit the old BitmapLayer
- When the rotationLayer is displayed, I display it onTop of the initial BitmapLayer using BitmapCenter (I could not find another way of positioning it where I want it). However this BitmapCenter seems to have 2 usages: one is positioning the layer, and two is setting the point around which the rotation will be made. How can I still position the rotation layer exactly onTop of the original BitmapLayer and still have the BitmapCenter (center of rotation) in the middle of the Bitmap?
- It seems that when I start the rotation, so the rotationLayer is created and loaded with my Bitmap, something happens with the alphaChannel I think, because the image becomes a little darker and translucent I think, everytime I assign the BitmapLayer.Bitmap to the RotationLayer.Bitmap. I noticed that by commenting the MasterAlpha:=200 line the image does not lose it's brightness, but now the empty parts of the Layer's rectangle turn to black when RotationLayer is visible. So it looks bad... Also when I do the MouseUP (so when I assign the rotated Bitmap to the BitmapLayer.Bitmap, some black lines remain visible on the exterior of the rotated image, so in the empty space). Any suggestions on how to keep the original image clean?
Please assist me in solving these 3 problems.
The working code so far is:
procedure TMainForm.myrotMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
l,r,t,b:single;
flrect:TFloatRect;
begin
ro:=TRotlayer.Create(imgView.Layers);
ro.Bitmap:=TBitmap32.Create;
with ro.Bitmap do
begin
BeginUpdate;
ro.Bitmap.Assign((Selection as TBitmapLayer).Bitmap);
TLinearResampler.Create(ro.Bitmap);
//ensure good looking edge, dynamic alternative to SetBorderTransparent
TCustomResampler(ro.Bitmap.Resampler).PixelAccessMode := pamTransparentEdge;
ro.BitmapCenter := FloatPoint(-(Selection as TBitmapLayer).Location.Left, -(Selection as TBitmapLayer).Location.Top);
// MasterAlpha := 200;
FrameRectS(BoundsRect, $FFFFFFFF);
DrawMode := dmBlend;
EndUpdate;
Changed;
end;
ro.Scaled := True;
(Selection as TBitmapLayer).Bitmap.Assign(ro.Bitmap);
end;
procedure TMainForm.myrotChange(Sender: TObject);
begin
ro.Angle := myRot.Position;
(Selection as TBitmapLayer).Bitmap.Assign(ro.Bitmap);
end;
procedure TMainForm.myrotMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
bmx:=TBitmap32.Create;
bmx.Assign((Selection as TBitmapLayer).Bitmap);
RotateBitmap(bmx, -(Round(ro.Angle)), false, clWhite32, true);
(Selection as TBitmapLayer).Bitmap.Assign(bmx);
bmx.Free;
ro.Free;
end;
The RotateBitmap function is picked from this SO question
Also there is a problem when rotating transparent images... Test them on your own using the above code and load some PNG with transparency and you will understand the problem.