Chào mừng đến với Diễn đàn lập trình - Cộng đồng lập trình.
Kết quả 1 đến 4 của 4
  1. #1
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Chậm là vì bạn dùng GetPixel, SetPixel. Hơn nữa ứng với mỗi pixel bạn lại tính sin & cos. Cách cải tiến là thay vì dùng GetPixel, SetPixel thì bạn truy cập trực tiếp vào vùng nhớ ảnh, thay vì tính sin, cos cho mỗi pixel bạn nên tính sin & cos trước.

    Mã:
    float sinTable[361];float cosTable[361];for(int i = 0; i <=360; i++]{sinTable = sin(i);cosTable = cos(i);}
    Thay vì sin(a), cos(a) thì bạn có thể thay bằng: sinTable[a % 360], cosTable[a % 360]

  2. #2
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Oài! ý tưởng thì có nhưng mà code kiểu setpixel lên dialog như vậy sao mà chạy nhanh được.

    Nếu bạn muốn xoay ảnh nhanh thì bạn phải giải quyết rất nhiều vấn đề.

    - Thực hiện trực tiếp trên 1 data image buffer. (Hay chính là struct của file BMP, nói cụ thể hơn là bạn xoay trên nội dung file BMP rồi mới dùng GDI vẽ BMP này ra). Lúc này 2 hàm setpixel và getpixel được thay bằng sự truy xuất dữ liệu trên mảng (setpixel là gán giá trị và getpixel là đọc giá trị) nên sẽ nhanh hơn rất nhiều.

    - Tối ưu phép toán. Đây ko phải là vấn đề dễ giải quyết. Thông thường CPU sẽ thực hiện phép + - hay dịch bit nhanh hơn so với phép nhân. Do đó hạn chế phép nhân càng nhiều càng tốt (dĩ nhiên nếu bắc buộc thì phải dùng). Trách thực hiện lặp đi lặp lại phép toán mà thay bằng gán kết quả vào biến.

    Ví dụ 1 trường hợp nhé:
    DWORD imgData[w*h]; là nội dung file IMAGE

    Giải sử bạn bạn duyệt hết toàn pixel của image và thay bằng màu đỏ 0x000000FF (ABGR khi lưu trên DWORD) thì bạn có thể chạy như sau:

    Mã:
    for (int i = 0; i < w; i++)
    {
           for(int j = 0; j < h; i++)
           {
                  // Set mau do
                  imgData[j*w + i] = 0x000000FF;
           }
    }
    Đó là 1 giải pháp nhưng nó ko tối ưu bằng cách dịch con trỏ
    Mã:
    int byteRun = w*h;
    DWORD *pixel = imgData;
    for (int i = 0; i < byteRun; i++)
    {
           *pixel = 0x000000FF;
           pixel++;
    }
    Thậm chí với con trỏ pixel ở vị trí (x,y) thì bạn vẫn có thể suy ra vị trí (x-1,y) hay (x+1,y) (x,y-1).... bằng cách trừ đi byteWidth = w*sizeof(DWORD)

    - SMID programing(xmmintrin.h) hay "data align".

    SMID đưa ra 1 giải pháp tính 1 lần có thể được 4 phép toán.
    Ví dụ như

    Để tăng giá trị 1 màu sắc
    R = R*2;
    G = G*2;
    B = B*2;
    A = A*2;

    Thì bạn có thể sử dụng 1 hàm _mm_mul_ps có thể tính chỉ 1 lần! tốc độ sẽ nhanh hơn nhiều. Nhưng để SMID xử lý được thì data phải được "align".

    Tham khảo

    - Còn vấn đề về chất lượng Image cũng khá dễ hiểu chính là do bạn làm tròn số.
    Ví dụ như khi xoay thì toạ độ pixel có thể là cón số (10.8137,20.1230)
    Trong khi bạn làm tròn thì nó trở thành (10,20)

    Nhưng lý ra phải cân bằng màu sắc giữa các pixel lận cận đó
    Ví dụ như tọa đô x=10.8 thì màu ở vị trí 11 chiếm 8 phần còn màu ở vị trí 10 chỉ chiếm 2 phần. Tương tự cho y.

    Trích dẫn Gửi bởi RL
    + 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.

    Còn đây là bài viết của RadicalLight lâu quá ko thấy him!
    Xoay ảnh

  3. #3
    Ngày tham gia
    Sep 2015
    Bài viết
    0

    Thuật qoán quay ảnh!!!

    Trưa nay, mình ngồi đọc bài này:http://forums.congdongcviet.com/showthread.php?t=10424 về đồ họa 3D của ZCoder87 nên thử viết 1 chương trình quay ảnh xem sao, kết quả thành công nhưng mà tốc độ thì cực chậm, chất lượng cũng thấp [IMG]images/smilies/redface.png[/IMG]. Nhưng nói chung là có thành công [IMG]images/smilies/biggrin.png[/IMG]. Công thức là: x' = x*Cos(α) - y*Sin(α), y' = x*Sin(α) + y*Cos(α) (Anh ZCoder viết nhầm trong bài của anh ấy công thức này ở chổ y*cos(α<font color="black">) [IMG]images/smilies/2.gif[/IMG]).
    ScreenShot:


    </font>

  4. #4
    Ngày tham gia
    Sep 2015
    Bài viết
    0
    Phức tạp quá nhỉ

 

 

Quyền viết bài

  • Bạn Không thể gửi Chủ đề mới
  • Bạn Không thể Gửi trả lời
  • Bạn Không thể Gửi file đính kèm
  • Bạn Không thể Sửa bài viết của mình
  •