Từ 1 tới 6 trên tổng số 6 kết quả

Đề tài: Image Rotation! Kỹ thuật xoay ảnh

  1. #1
    Ngày gia nhập
    10 2007
    Bài viết
    169

    Mặc định Image Rotation! Kỹ thuật xoay ảnh

    + Image rotation là công việc xoay ảnh quanh một điểm nào đó. Các bạn xem hình dưới đây:


    + Để xoay cả image thì chúng ta phải lần lược xoay từng pixel một trên image đó. Theo hình, Source là điểm gốc và Dest là điểm sau khi xoay một góc a1 độ. Do đó, nếu chúng ta tính đc tọa độ của Dest thì xem như xong.

    C++ Code:
    1. DW = R*cos(a3) = R*cos(a1 + a2) = R*(cos(a1)*cos(a2) - sin(a1)*sin(a2))
    2. DH = R*sin(a3)   = R*sin (a1 + a2) = R*(sin(a1)*cos(a2) + cos(a1)*sin(a2))
    3.  
    4. cos(a2) = SW/R
    5. sin(a2)  = SH/R
    6.  
    7. ->
    8.  
    9. DW = R*(cos(a1)*SW/R - sin(a1)*SH/R)
    10. DH = R*(sin(a1)*SW/R + cos(a1)*SH/R)
    11.  
    12. // or
    13. DW = cos(a1)*SW - sin(a1)*SH
    14. DH = sin(a1)*SW + cos(a1)*SH
    + Với a1 là góc ta cần xoay, xem như việc tính Dest đả xong, áp dụng công thức này vào từng pixel trên source image, ta sẻ tính đc ảnh kết quả:

    Sau đây là code:
    C++ Code:
    1. inline Void GImage24_Dl::Rotate(GBuffer* pDestImage,Int32 CenterX,Int32 CenterY,Int32 DestX,Int32 DestY,Float Degree,Bool bUseAntiAliasing)
    2. {
    3.     #pragma region Rotate
    4.     // Get image size and Dest pointer
    5.     UInt32 DestWidth = pDestImage->GetWidth(),DestHeight = pDestImage->GetHeight(),SourceWidth = m_ImageWidth,SourceHeight = m_ImageHeight;
    6.  
    7.     // PI = 3.1415926535897932384626433832795
    8.     Double Rad = -Degree*0.017453292519943295769236907684886;
    9.     UInt8 nBits = 14;
    10.     Int32 CosVl = Int32(cos(Rad)*16384);
    11.     Int32 SinVl = Int32(sin(Rad)*16384);
    12.  
    13.     // Calc source image offset
    14.     Int32 OffsetX = CenterX - DestX,OffsetY = CenterY - DestY;
    15.     Int32 DwSin,DwCos,DhSin,DhCos,SourceX,SourceY;
    16.  
    17.     // Calc bound rectangle
    18.     Int32 TmpX,TmpY,MinX,MinY,MaxX,MaxY;
    19.  
    20.     // Top - Left
    21.     TmpX = DestX - CenterX;
    22.     TmpY = DestY - CenterY;
    23.     MinX = ((TmpX*CosVl - TmpY*SinVl) >> nBits) + CenterX;
    24.     MinY = ((TmpY*CosVl + TmpX*SinVl) >> nBits) + CenterY;
    25.     MaxX = MinX;
    26.     MaxY = MinY;
    27.  
    28.     // Top - Right
    29.     TmpX = DestX + SourceWidth - CenterX;
    30.     TmpY = DestY - CenterY;
    31.     SourceX = ((TmpX*CosVl - TmpY*SinVl) >> nBits) + CenterX;
    32.     SourceY = ((TmpY*CosVl + TmpX*SinVl) >> nBits) + CenterY;
    33.     if(SourceX < MinX) MinX = SourceX;
    34.     else if(MaxX < SourceX) MaxX = SourceX;
    35.     if(SourceY < MinY) MinY = SourceY;
    36.     else if(MaxY < SourceY) MaxY = SourceY;
    37.  
    38.     // Bottom - Left
    39.     TmpX = DestX - CenterX;
    40.     TmpY = DestY + SourceHeight - CenterY;
    41.     SourceX = ((TmpX*CosVl - TmpY*SinVl) >> nBits) + CenterX;
    42.     SourceY = ((TmpY*CosVl + TmpX*SinVl) >> nBits) + CenterY;
    43.     if(SourceX < MinX) MinX = SourceX;
    44.     else if(MaxX < SourceX) MaxX = SourceX;
    45.     if(SourceY < MinY) MinY = SourceY;
    46.     else if(MaxY < SourceY) MaxY = SourceY;
    47.  
    48.     // Bottom - Right
    49.     TmpX = DestX + SourceWidth - CenterX;
    50.     TmpY = DestY + SourceHeight - CenterY;
    51.     SourceX = ((TmpX*CosVl - TmpY*SinVl) >> nBits) + CenterX;
    52.     SourceY = ((TmpY*CosVl + TmpX*SinVl) >> nBits) + CenterY;
    53.     if(SourceX < MinX) MinX = SourceX;
    54.     else if(MaxX < SourceX) MaxX = SourceX;
    55.     if(SourceY < MinY) MinY = SourceY;
    56.     else if(MaxY < SourceY) MaxY = SourceY;
    57.  
    58.     // Checking coordinate
    59.     if(MaxX < 0 || MaxY < 0 || MinX >= Int32(DestWidth) || MinY >= Int32(DestHeight)) return;
    60.  
    61.     // Adjust coordinate
    62.     if(MinX < 0) MinX = 0;
    63.     if(MinY < 0) MinY = 0;
    64.     if(MaxX >= Int32(DestWidth)) MaxX = DestWidth - 1;
    65.     if(MaxY >= Int32(DestHeight)) MaxY = DestHeight - 1;
    66.  
    67.     // Init dest pointer
    68.     UInt32 Offset = DestWidth + MinX - MaxX;
    69.     Color24* pDestPtr = (Color24*)pDestImage->GetBuffer(MinX,MinY),*pSourcePtr = m_pBuffer;
    70.  
    71.     // Init DH offset
    72.     DhCos = (MinY - CenterY)*CosVl + (OffsetY << nBits);
    73.     DhSin = (MinY - CenterY)*SinVl;
    74.  
    75.     // Calc DW offset
    76.     DwCos = (MinX - CenterX)*CosVl + (OffsetX << nBits) + DhSin;
    77.     DwSin = DhCos - (MinX - CenterX)*SinVl;
    78.  
    79.     for(Int32 j = MinY;j < MaxY;++j)
    80.     {
    81.         // Set source pos
    82.         SourceX = DwCos;
    83.         SourceY = DwSin;
    84.  
    85.         for(Int32 i = MinX;i < MaxX;++i)
    86.         {
    87.             if(UInt32(SourceX >> nBits) < SourceWidth && UInt32(SourceY >> nBits) < SourceHeight) *pDestPtr = pSourcePtr[(SourceY >> nBits)*SourceWidth + (SourceX >> nBits)];
    88.         //  else pDestPtr->Blue = 255;
    89.  
    90.             // Next pixel
    91.             pDestPtr++;
    92.  
    93.             // Inc DW offset
    94.             SourceX += CosVl;
    95.             SourceY -= SinVl;
    96.         }
    97.  
    98.         // Next line
    99.         pDestPtr += Offset;
    100.  
    101.         // Inc DW offset
    102.         DwCos += SinVl;
    103.         DwSin += CosVl;
    104.     }
    105.     #pragma endregion
    106. }
    + Nhưng nếu bạn rotate theo như trên thì ảnh sẻ bị bể hạt rất nhiều, vì vậy, với mỗi pixel kết quả , bạn phải tính xem tỉ lệ của nó với các pixel xung quanh là bao nhiêu, rồi dùng cách cộng dồn các màu Red,Green,Blue lại. Việc tính tỉ lệ này ko mấy khó nên các bạn tự tính lấy vậy , cho đầu óc nó vận động một tí!
    VD: rotate 30 độ, pixel kết quả có tọa độ (1.25,2.75) thì có bao nhiêu % màu của pixel top-left,top-right,bottom-left,bottom-right.


    Đây là hình mình test, dùng Paint nén sang JPG nên chất lượng hơi tệ!


    - Hình này mình đả dùng anti-aliasing để ko bị bể hình. Các bạn có thể thấy chử "PI" bên trài nhìn rỏ hơn hẳn bên phải.

    - Ngoài ra, các bạn cũng có thể cho image vừa rotate vừa phóng to hay thu nhỏ, xoay theo hình sin,... !

    Nhóm mình đang làm đến đây, nhưng việc thì nhiều mà người thì ít, nếu bạn nào có hứng thú với phần này thì có thể tham gia chung với tụi mình .
    Đã được chỉnh sửa lần cuối bởi RadicalLight : 17-03-2009 lúc 03:59 PM. Lý do: Update image!

  2. #2
    Ngày gia nhập
    01 2009
    Bài viết
    201

    Bác đưa đầy đủ 1 Project lên em test thử được không thank bác

  3. #3
    Ngày gia nhập
    11 2008
    Nơi ở
    vngameday.com
    Bài viết
    62

    Bác đưa đầy đủ 1 Project lên em test thử được không thank bác
    Bọn mình chưa thể public đc bởi vì chương trình đang rối tung rối mù lên, có đôc 2 đứa làm, lên cần thêm người nữa, nếu ai muốn tham gia thì PM Rlight nhé.
    vngameday.com - khi niềm đam mê luôn rực cháy. Rất mong nhận được sự đóng góp từ các bạn...

  4. #4
    Ngày gia nhập
    09 2006
    Nơi ở
    /usr/share/.hack@
    Bài viết
    1,433

    Hỏi xíu, nếu tại điểm ban đầu xoay ảnh đi, thì điểm ảnh cũ có cần xóa không nhỉ?
    Thấy trong hình test là cùng một ảnh nhưng mà 1 cái lưu vệt đen của điểm ảnh cũ.
    - Nếu mà điểm ảnh A xoay lại trùng vào vị trí điểm ảnh cũ của điểm ảnh B, thì đặc điểm vị trí đó thế nào nhỉ? File ảnh có tăng kích thước không
    None!

  5. #5
    Ngày gia nhập
    10 2007
    Bài viết
    169

    + Đả nói mình bị...yếu tim mà sao cứ hù hoài thế ko biết ... T_T!

    + Xoay trong cùng một image là không thể vì bị overlap (trừ khi gốc tọa độ nằm...ngoài vùng phủ sóng của image)
    + Màu đen là của ảnh nền, còn hình bên trên là hình mình xoay. Nghĩa là xoay từng pixel trên ảnh gốc, sau đó set lên ảnh nền.
    + Việc tăng kích thước dễ ợt ấy mà, tìm max,min của mấy cái rear-point sau đó tạo buffer theo size đó thôi.

    Bác đưa đầy đủ 1 Project lên em test thử được không thank bác
    - Nếu bạn muốn thì vào đây: http://code.google.com/p/goldensun/
    - Bạn xem trong phần Source ấy, vì code mới mình chưa update trong Download.
    Đã được chỉnh sửa lần cuối bởi RadicalLight : 17-03-2009 lúc 08:27 PM. Lý do: Add!

  6. #6
    Ngày gia nhập
    10 2006
    Nơi ở
    In Your Bugs
    Bài viết
    823

    Mặc định Image Rotation! Kỹ thuật xoay ảnh

    Spam: Lâu quá không gặp RL, học tốt nhé bạn.

Các đề tài tương tự

  1. Opengl , xoay hình vuông nhưng nó xoay luôn cả hình xuông, tại sao ?
    Gửi bởi kwideur trong diễn đàn Thắc mắc lập trình Visual C++
    Trả lời: 2
    Bài viết cuối: 20-09-2012, 02:59 AM
  2. Thuật toán xác định ảnh chuyển động và xoay?
    Gửi bởi voicewithin trong diễn đàn Thắc mắc lập trình C/C++/C++0x
    Trả lời: 2
    Bài viết cuối: 23-03-2012, 12:00 PM
  3. Thuật toán xoay chuỗi 90 độ theo chiều kim đồng hồ
    Gửi bởi devildn132 trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 1
    Bài viết cuối: 03-05-2011, 10:49 AM
  4. Cần giúp hàm trong kỹ thuật xoay vòng (modilo)
    Gửi bởi tranbaho trong diễn đàn Nhập môn lập trình C/C++
    Trả lời: 11
    Bài viết cuối: 06-05-2010, 11:48 AM
  5. Image Rotation
    Gửi bởi RadicalLight trong diễn đàn Tutorials và Thủ thuật Visual C++
    Trả lời: 3
    Bài viết cuối: 21-08-2009, 10:59 AM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn