Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Gráficos
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 12-03-2008
Avatar de mrnovice
mrnovice mrnovice is offline
Miembro
 
Registrado: oct 2006
Posts: 163
Poder: 18
mrnovice Va por buen camino
Rotación de bitmap caso especial

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; //Copy PixelFormat
  {$IFDEF Paletted}
   BitmapRotated.Palette := CopyPalette(BitmapOriginal.Palette); //Copy 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; //Prevent Repeated Calls to TBitMap.Width
  BH := BitmapOriginal.Height - 1; //Prevent Repeated Calls to TBitMap.Height
  iRot := (2 * iRotationAxis) + 1; //Simplify Calculation within Inner Loop
  jRot := (2 * jRotationAxis) + 1; //Simplify Calculation within Outer Loop
  RowRotated     := BitmapRotated.ScanLine[BH]; //Last BitmapRotated Scanline
  POriginalStart := BitmapOriginal.ScanLine[0]; //First BitmapOriginal Scanline
  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;{for i}
      Dec(Integer(RowRotated), ScanLineBytes);
    end;{for j}

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;// case
      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   //1/8/00
       BEGIN //for j
            RowRotatedT := BitmapRotated.Scanline[ j ] ;
           jPrime := 2*j - NewHeight + 1 ;
           FOR i := Rwi DOWNTO 0 DO
            BEGIN //for i
                 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 //for i
       END;//for j
  end;//non-zero rotation
    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;{with}
 end;{Rotate Bitmap}

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
Responder Con Cita
  #2  
Antiguo 12-03-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Revisaste el Truco 455? dudo que tu comentario haya sido de éste porque el mismo no se vale de movimiento de pixeles ni de calculos en punteros ScanLine, sino que mediante la API realiza las rotaciónes.

Solo necesitas convertir el JPEG a BMP y utilizar la función.

Saludos
Responder Con Cita
  #3  
Antiguo 12-03-2008
Avatar de mrnovice
mrnovice mrnovice is offline
Miembro
 
Registrado: oct 2006
Posts: 163
Poder: 18
mrnovice Va por buen camino
Rotación, caso especial

Saludos, Muchas gracias, este no lo había visto, parece más sencillo, luego te comentó cómo me fue,voy a probarlo, una pregunta osea las versiones scanline o pixeles son métodos antiguos, ya no se usan, son como la base para lo que tenemos en la actualidad?.

Muchas gracias
Responder Con Cita
  #4  
Antiguo 12-03-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Cita:
Empezado por mrnovice Ver Mensaje
...una pregunta osea las versiones scanline o pixeles son métodos antiguos, ya no se usan, son como la base para lo que tenemos en la actualidad?.
En ningún momento he sugerido tal cosa, y si fue así me retracto. Acceder a los pixeles es útil para comprender la abstracción de los gráficos... al fin y a cabo un pixel es la mínima unidad utilizada por el mismo monitor. Y usarla no es nada malo en pequeñas medidas.

Usar "ScanLine" es acceder a la matriz de pixeles del gráfico en cuestión, lo que acelera en gran medida la modificación de sus datos pues es la modificación del buffer en memoria que posteriormente será actualizada.

Qué tenemos en la "actualidad"... en realidad si pudiésemos ver el código que realiza la API, estaríamos viendo operaciones en memoria con senos y cosenos. La supuesta ventaja es que una empresa con tantos $$$$, puede pagar a buenos matemáticos que optimicen dicho código (o que por lo menos lo busquen e implementen).

Saludos

Última edición por cHackAll fecha: 12-03-2008 a las 18:44:44. Razón: F7 (decía "dódigo")
Responder Con Cita
  #5  
Antiguo 12-03-2008
Avatar de mrnovice
mrnovice mrnovice is offline
Miembro
 
Registrado: oct 2006
Posts: 163
Poder: 18
mrnovice Va por buen camino
Rotación, caso especial

Muchas gracias, saludos.
Muy clara la explicación, mejor no pudo haber quedado.
Ah! no lo sugeriste, lo que pasa es que me quedo la duda, porque según investigaba, encontraba nuevos métodos, me imaginaba que cada vez se optimizaba y creo de ahí me vino la confusión.
Si te fijas he tratado de encontrar la solución a rotar pero uff creo que hay diversidad de métodos,sólo que me perdí y no supe si estoy haciendo pasos innecesario.
Ah!!!!!!!, me llamó la atención, qué es una verdad qué, pues en cierta manera las grandes empresas pagan $$$$ para optimizar y esto ayude al avance de la tecnología.
Gracias y arriba club Delphi!!!!
Responder Con Cita
  #6  
Antiguo 12-03-2008
Avatar de mrnovice
mrnovice mrnovice is offline
Miembro
 
Registrado: oct 2006
Posts: 163
Poder: 18
mrnovice Va por buen camino
Ya lo probe

mmm, si funciona, y me gusta el rendimiento, pero me deja un espacio morado y algunos bmp no me los lee......serà que no lee bmps grandes?
voy a tratr de modificar el código para hacerlo funcionar, saludos
Responder Con Cita
  #7  
Antiguo 12-03-2008
Avatar de cHackAll
[cHackAll] cHackAll is offline
Baneado?
 
Registrado: oct 2006
Posts: 2.159
Poder: 20
cHackAll Va por buen camino
Cita:
Empezado por mrnovice Ver Mensaje
...me deja un espacio morado y algunos bmp no me los lee......serà que no lee bmps grandes?
No es morado, es clFuchsia y esta hecho así para realizar las modificaciones en tiempo de ejecución y que el espacio vacío quede como tal en un componente que procese el color de transparencia. Puedes cambiarlo sin problema.

No está probado, pero espero que dicha función procese BMPs de decenas de mega pixeles. Con respecto a los BMPs que no reconoce... si tienes uno pequeño súbelo para corregir el truco (si es que realmente es necesario)

Saludos
Responder Con Cita
  #8  
Antiguo 13-03-2008
Avatar de mrnovice
mrnovice mrnovice is offline
Miembro
 
Registrado: oct 2006
Posts: 163
Poder: 18
mrnovice Va por buen camino
Caso raro

Pues estuve investigando aunque muy poco los que no me agarraba era bmps de muchos pixeles aprox su tamaño era 24MB, seguirè invesitgando gracias
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Rotacion de botones o paneles dave.jason C++ Builder 1 17-12-2007 18:40:28
Caso Especial en Starting With.... AGAG4 Firebird e Interbase 2 07-02-2005 21:37:49
Ayuda con rotacion de graficas jose_2057111 Gráficos 1 17-11-2004 06:38:42
Especial calabazas ;-) Investment Humor 1 05-10-2004 08:27:05
como hago un sistema de rotacion de imagenes alachaise PHP 9 09-09-2004 09:45:09


La franja horaria es GMT +2. Ahora son las 09:57:05.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi