Forum: Rotera bmp

Forum huvudsida -> Programmering -> Rotera bmp

Sidor: 1

Till botten

Celeron 08:08 - 10:e April 2005 | Post #1
Medlem
Inlägg: 418


Skicka PM
Hur roterar man en .bmp (bitmap) i Win API?

-------------------------
Det viktigaste är att ha roligt! Har ny hemsida: http://www.freewebs.com/cpperik/



sdac 20:33 - 11:a April 2005 | Post #2
Medlem
Inlägg: 235


Skicka PM
Win32-API:n till bilder? ;O Läs om GDI.




madah 01:52 - 13:e April 2005 | Post #3
Medlem
Inlägg: 28


Skicka PM
http://www.codeguru.com/Cpp/G-M/gdi/article.php/c3693/

Fast koden till den ovan verkade vara lite rörig, här är lite bättre pseudo-kod:

SinTheta = Sin( AngleInRadians );
CosTheta = Cos( AngleInRadians );

CenterX = Width / 2;
CenterY = Height / 2;

for(int Y=0; Y<Height; Y++)
{
    for(int X=0; X<Width; X++)
    {
        SourceX = CenterX + (X-CenterX)*CosTheta - (Y-CenterY)*SinTheta;
        SourceY = CenterY + (X-CenterY)*SinTheta + (Y-CenterY)*CosTheta;
    
        if(    ( SourceX >= 0 ) &&        
            ( SourceX < Width ) &&    
            ( SourceY >= 0 ) &&        
            ( SourceY < Height ) )
        {    
            DestBitmap[X, Y] = SourceBitmap[SourceX, SourceY];
        }
        else
        {
            // ge svart färg till området utanför bilden
            DestBitmap[X, Y] = 0;
        }
    }
}






Celeron 06:48 - 13:e April 2005 | Post #4
Medlem
Inlägg: 418


Skicka PM
Jag förstår inte riktigt. Kan du förklara lite mer vad dom olika sakerna gör. Jag förstår att det loopar igenom alla y pixlar och x pixlar och vad CenterY och CenterX är, men vad är t ex DestBitmap?

-------------------------
Det viktigaste är att ha roligt! Har ny hemsida: http://www.freewebs.com/cpperik/



void 13:21 - 13:e April 2005 | Post #5
Medlem
Inlägg: 63


Skicka PM
Han gör en kopia av bilden.
För varje pixel i utbilden (den roterade) beräknar han en punkt i inbilden och sätter dess pixelvärde i den roterade bilden.

OK om man gör det en gång, men ska du rotera bilden "dynamiskt" bör du nog använda interna metoder i ditt grafikbibliotek (SDL,GDI, etc.).

Dessutom kör han med nearest-inperpolation (alltså ingen interpolation)... det blir inte så snyggt =)

-------------------------
Ingen signatur!



Celeron 13:33 - 13:e April 2005 | Post #6
Medlem
Inlägg: 418


Skicka PM
Jag använder alltså GDI. Har inte hittat någon sådan funktion som roterar en bild. Vet du någon?

-------------------------
Det viktigaste är att ha roligt! Har ny hemsida: http://www.freewebs.com/cpperik/



void 13:51 - 13:e April 2005 | Post #7
Medlem
Inlägg: 63


Skicka PM
En googling på "gdi rotate" ger:
http://www.codeguru.com/Cpp/G-M/gdi/article.php/c3693/

-------------------------
Ingen signatur!



Celeron 15:53 - 13:e April 2005 | Post #8
Medlem
Inlägg: 418


Skicka PM
Det är samma länk som madha gav mig och den gör mig inte klokare...

-------------------------
Det viktigaste är att ha roligt! Har ny hemsida: http://www.freewebs.com/cpperik/



madah 17:19 - 13:e April 2005 | Post #9
Medlem
Inlägg: 28


Skicka PM
    Citat av void:
Dessutom kör han med nearest-inperpolation (alltså ingen interpolation)... det blir inte så snyggt =)


,,sch då Smiley

Fortfarande pseudo-kod:

  1. // roterar SourceBitmap och resultatet hamnar i DestinationBitmap
  2. // rotationsvinkel:
  3. float AngleInRadians = (PI/180) * AngleInDegrees;
  4. float SinTheta = Sin( AngleInRadians );
  5. float CosTheta = Cos( AngleInRadians );
  6. // vilken position man vill rotera kring:
  7. float CenterX = Width / 2.0;
  8. float CenterY = Height / 2.0;
  9. for(int Y=0; Y<Height; Y++)
  10. {
  11. for(int X=0; X<Width; X++)
  12. {
  13. float SourceXF = CenterX + (X-CenterX)*CosTheta - (Y-CenterY)*SinTheta;
  14. float SourceYF = CenterY + (X-CenterY)*SinTheta + (Y-CenterY)*CosTheta;
  15. // dela upp positionen till heltalsdel och decimaldel
  16. // t ex: SourceXF=3.5375 => SourceX=3 SourceXF=0.5375
  17. // floor() används för att se till så avrundningen blir rätt:
  18. // floor(0.99) = 0.00, floor(-0.99) = -1.00
  19. int SourceX = (int)floor(SourceXF);
  20. int SourceY = (int)floor(SourceYF);
  21. // fixa så SourceXF/YF är mellan 0.0 och 1.0
  22. SourceXF -= SourceX;
  23. SourceYF -= SourceY;
  24. // (bi)linear interpolation
  25. // utpixelvärdet bestäms av de fyra kringliggande pixlarna,
  26. // hur mycket av varje pixel bestäms av SourceXF och SourceYF,
  27. // dvs decimaldelen av positionen
  28. float Pixel0 = SourceBitmap[SourceX, SourceY];
  29. float Pixel1 = SourceBitmap[SourceX+1, SourceY];
  30. float Pixel2 = SourceBitmap[SourceX, SourceY+1];
  31. float Pixel3 = SourceBitmap[SourceX+1, SourceY+1];
  32. float Pixel01 = SourceXF * (Pixel1 - Pixel0) + Pixel0;
  33. float Pixel23 = SourceXF * (Pixel3 - Pixel2) + Pixel2;
  34. float Pixel0123 = SourceYF * (Pixel23 - Pixel01) + Pixel01;
  35. DestinationBitmap[X, Y] = Pixel0123;
  36. }
  37. }


Om man vill kolla så man inte hamnar utanför bilden, så byt ut det understa i förra mot detta:

  1. // (bi)linear interpolation
  2. for(int i=0; i<4; ++i)
  3. {
  4. int XP = SourceX + (i & 1);
  5. int YP = SourceY + (i / 2);
  6. if( ( XP >= 0 ) && ( XP < Width ) &&
  7. ( YP >= 0 ) && ( YP < Height ) )
  8. {
  9. Pixel[i] = SourceBitmap[XP, YP];
  10. }
  11. else
  12. {
  13. // ge svart färg till området utanför bilden
  14. Pixel[i] = 0;
  15. }
  16. }
  17. float Pixel01 = SourceXF * (Pixel[1] - Pixel[0]) + Pixel[0];
  18. float Pixel23 = SourceXF * (Pixel[3] - Pixel[2]) + Pixel[2];
  19. float Pixel0123 = SourceYF * (Pixel23 - Pixel01) + Pixel01;
  20. DestinationBitmap[X, Y] = Pixel0123;


Koden ovan fungerar egentligen bara bra med gråskalebilder. Om det är färg måste man separera och köra interpoleringen separat för röd, grön och blå. Jag tog inte med det för att inte röra till koden, men jag kanske kan skriva ihop en hel tutorial vid ett senare tillfälle.


Senast redigerad 17:22 - 13:e April 2005


Celeron 15:21 - 14:e April 2005 | Post #10
Medlem
Inlägg: 418


Skicka PM
Tack. Nu förstår jag lite mer!

-------------------------
Det viktigaste är att ha roligt! Har ny hemsida: http://www.freewebs.com/cpperik/



Sidor: 1

Forum huvudsida -> Programmering -> Rotera bmp
Atom feed

Du får inte posta i den här tråden | Till toppen