Saludos, necesito ayuda help!, soy un caso perdido

, miren mi situación, es que busqué sobre como rotar una imagen JPEG
- Pero esta requería ser rotado mediante una bitmap, y seguí buscando
- Ví en los trucos y efectivamente funcionó, y me ha sido muy útil, sólo que para imágenes muy grandes se tarda(ya que utiliza el método por píxeles), y seguí buscando
- Encontré una página efg lab creo, donde te muestra optimizaciones por medio del scanline y senos y thetas,y funcionó mejor y dentro de la página venía una optimización de el mismo a 400 X eso hubiera sido perfecto sí,al rotar no cortara la imagen a 90° y 270° ya que este funciona para cuadros(REF1) ya que al voltearlo me rellena con negro y yo solo quería rotarlo jejeXD
- busqué otra opción pero es un poco más complicada y un poco menos efectiva pero funciona, sólo que tuve problemas al adaptarlo a un JPEG y a eventos on clic(REF2)
Códigos
REF1
Código Delphi
[-]
begin
BitmapRotated.Width := BitmapOriginal.Width;
BitmapRotated.Height := BitmapOriginal.Height;
BitmapRotated.PixelFormat := BitmapOriginal.PixelFormat; {$IFDEF Paletted}
BitmapRotated.Palette := CopyPalette(BitmapOriginal.Palette); {$ENDIF}
StartTime := GetTickCount;
try iRotationAxis := SpinEditI.Value
except iRotationAxis := 0
end;
try jRotationAxis := SpinEditJ.Value
except jRotationAxis := 0
end;
Theta := -(SpinEditThetaDegrees.Value + SpinEditThetaDegreesHundredths.Value/100) * PI / 180;
Edit1.text:=' Theta= '+FloatToStr(Theta)+' spe/100= '+ FloatToStr(SpinEditThetaDegreesHundredths.Value/100);
sinTheta := SIN(Theta);
cosTheta := COS(Theta);
ScanlineBytes := Integer(BitmapOriginal.Scanline[1])- Integer(BitmapOriginal.Scanline[0]);
BW := BitmapOriginal.Width - 1; BH := BitmapOriginal.Height - 1; iRot := (2 * iRotationAxis) + 1; jRot := (2 * jRotationAxis) + 1; RowRotated := BitmapRotated.ScanLine[BH]; POriginalStart := BitmapOriginal.ScanLine[0]; for j := BH downto 0 do
begin
jPrime := (2 * j) - jRot;
jPrimeSinTheta := jPrime * sinTheta;
jPrimeCosTheta := jPrime * cosTheta;
POriginal := POriginalStart;
for i := BW downto 0 do
begin
iPrime := (2 * i) - iRot;
iPrimeRotated := ROUND(iPrime * cosTheta - jPrimeSinTheta);
iOriginal := (iPrimeRotated - 1) div 2 + iRotationAxis;
if (iOriginal >= 0) and (iOriginal <= BW) then
begin
jPrimeRotated := ROUND(iPrime * sinTheta + jPrimeCosTheta);
jOriginal := (jPrimeRotated - 1) div 2 + jRotationAxis;
if (jOriginal >= 0) and (jOriginal <= BH) then begin
RowOriginal := Pointer(Integer(POriginal) + (jOriginal * ScanLineBytes));
RowRotated[i] := RowOriginal[iOriginal];
end else {$IFDEF Paletted}RowRotated[i] := 0;{$ELSE}RowRotated[i] := Black;{$ENDIF}
end else {$IFDEF Paletted} RowRotated[i] := 0; {$ELSE} RowRotated[i] := Black;{$ENDIF}
end;
Dec(Integer(RowRotated), ScanLineBytes);
end;
REF2
Código Delphi
[-]
with BitMapOriginal do
begin
case pixelformat of
pfDevice:begin
nbits := GetDeviceCaps( Canvas.Handle,BITSPIXEL )+1 ;
nbytes := nbits div 8;
if (nbytes>0)and(nbits mod 8 <> 0) then exit;
end;
pf24bit: nBytes:=3;
pfCustom:begin
GetObject( Handle, SizeOf(DIB), @DIB );
nbits := DIB.dsBmih.biSizeImage;
nbytes := nbits div 8;
if (nbytes>0)and(nbits mod 8 <> 0) then exit;
end;
else exit;
end; BitmapRotated.Assign( BitMapOriginal);
sinTheta := SIN( theta ); cosTheta := COS( theta );
NewWidth := ABS( ROUND( Height*sinTheta) ) + ABS( ROUND( Width*cosTheta ) );
NewHeight := ABS( ROUND( Width*sinTheta ) ) + ABS( ROUND( Height*cosTheta) );
if ( ABS(theta)*MAX( width,height ) ) > 1 then
begin
BitmapRotated.Width := NewWidth;
BitmapRotated.Height := NewHeight;
iRotationAxis := width div 2;
jRotationAxis := height div 2;
Rwi := NewWidth - 1;
Rht := NewHeight - 1;
Owi := Width - 1;
Oht := Height - 1;
TransparentT := pRGBtripleArray( Scanline[ Oht ] )[0]; FOR j := Rht DOWNTO 0 DO BEGIN RowRotatedT := BitmapRotated.Scanline[ j ] ;
jPrime := 2*j - NewHeight + 1 ;
FOR i := Rwi DOWNTO 0 DO
BEGIN iPrime := 2*i - NewWidth + 1;
iOriginal := ( ROUND( iPrime*CosTheta - jPrime*sinTheta ) -1 + width ) DIV 2;
jOriginal := ( ROUND( iPrime*sinTheta + jPrime*cosTheta ) -1 + height) DIV 2 ;
IF ( iOriginal >= 0 ) AND ( iOriginal <= Owi ) AND ( jOriginal >= 0 ) AND ( jOriginal <= Oht )THEN
begin RowRotatedT[i] := pRGBtripleArray( Scanline[jOriginal] )[iOriginal];end
ELSE
begin RowRotatedT[i] := TransparentT; end;
END END; end; sicoPhi := sicodiPoint( POINT( width div 2, height div 2 ),oldaxis );
with sicoPhi do begin
NewAxis.x := newWidth div 2 + ROUND( di*(CosTheta*co - SinTheta*si) );
NewAxis.y := newHeight div 2- ROUND( di*(SinTheta*co + CosTheta*si) );
end;
end;
end;
Son fragmentos, nose si alguien se le haga parecido al código, el punto es que si me pudieran ayudar a rotar rectangulos que de hecho las imágenes tamaño carta sin escalar y pués me gustaria saber si se pudiera modificar la ref1 para que este funcione con rectangulos u optimizar la ref2 ó no si hayan escuchado del BitBlt es bueno? me la estoy complicando mucho, también aplicar el procedimiento rotatebitmap en eventos onclick es decir tener un Bitmap:bitmap global, es decir que funcione el rotar como el Microsoft Office Picture Manager