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.
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
Ngọc Bích xanh bản chất thuộc dòng đá đá hoa (jade). Và cẩm thạch là tên gọi chung của ngọc bích. Vì thực chất chúng thuộc dòng đá đa khoáng được hình thành từ chất Silicat dưới dạng dioxy. Ngọc bích...
Chia sẻ Vòng tay ngọc bích xanh là...