2009-08-31 26 views
15

Tôi đã viết một dịch vụ web để thay đổi kích cỡ hình ảnh đã tải lên của người dùng và tất cả hoạt động chính xác từ một góc nhìn chức năng, nhưng nó làm cho mức sử dụng CPU tăng đột biến mỗi lần sử dụng. Nó đang chạy trên Windows Server 2008 64 bit. Tôi đã cố gắng biên dịch đến 32 và 64 bit và có được kết quả tương tự.Hiệu suất thay đổi kích thước hình ảnh trong C# và .NET 3.5

Trái tim của dịch vụ này là chức năng này:

private Image CreateReducedImage(Image imgOrig, Size NewSize) 
{ 
    var newBM = new Bitmap(NewSize.Width, NewSize.Height); 
    using (var newGrapics = Graphics.FromImage(newBM)) 
    { 
     newGrapics.CompositingQuality = CompositingQuality.HighSpeed; 
     newGrapics.SmoothingMode = SmoothingMode.HighSpeed; 
     newGrapics.InterpolationMode = InterpolationMode.HighQualityBicubic; 
     newGrapics.DrawImage(imgOrig, new Rectangle(0, 0, NewSize.Width, NewSize.Height)); 
    } 

    return newBM; 
} 

tôi đặt một hồ sơ về các dịch vụ và nó dường như cho thấy đại đa số thời gian là chi tiêu trong GDI + thư viện riêng của mình và không có nhiều để đạt được trong mã của tôi.

Câu hỏi: Tôi có đang làm điều gì đó không hiệu quả trong mã của mình ở đây không? Nó có vẻ phù hợp với ví dụ tôi đã thấy.

Có lợi ích nào khi sử dụng các thư viện ngoài GDI + không? Các tiêu chuẩn tôi đã thấy dường như chỉ ra rằng GDI + cũng so sánh với các thư viện khác nhưng tôi không tìm thấy đủ những điều này để tự tin.

Có lợi ích nào bằng cách sử dụng các khối "mã không an toàn" không?

Vui lòng cho tôi biết nếu tôi không bao gồm đủ mã ... Tôi rất vui khi được đặt nhiều như yêu cầu nhưng không muốn gây khó chịu trong bài đăng.

+0

Nếu bạn chạy điều này trong một vòng lặp chặt chẽ, bạn có thể xử lý bao nhiêu hình ảnh/giây ở kích thước hình ảnh đầu vào/đầu ra nào? –

+0

Nếu tôi chỉ chạy hình ảnh thay đổi kích thước một phần của mã cục bộ tôi có thể thay đổi kích thước 1000 hình ảnh trong 45 giây hoặc lâu hơn. Nhập 873x655 và đổi kích thước và cắt thành 300x250. –

+0

Điều gì đó chắc chắn sai. [Thư viện ImageResizer cho ASP.NET] (http://imageresizing.net) sử dụng GDI + nội bộ và có * nhiều * thông lượng cao hơn. Tôi nghi ngờ đó là do cách I/O được xử lý - đệm luồng tệp vào bộ nhớ trước khi tạo một cá thể Image/Bitmap loại bỏ một số lỗi đồng thời nhất định. –

Trả lời

6

Xử lý hình ảnh thường là một hoạt động tốn kém. Bạn phải nhớ rằng hình ảnh màu 32 bit được mở rộng trong bộ nhớ thành chiều rộng 4 * pixel chiều rộng * pixel trước khi ứng dụng của bạn thậm chí bắt đầu bất kỳ loại xử lý nào. Sự tăng đột biến chắc chắn được mong đợi đặc biệt là khi thực hiện bất kỳ loại xử lý pixel nào.

Điều đó đang được nói, nơi duy nhất tôi có thể thấy bạn trong việc có thể tăng tốc quá trình hoặc giảm tác động lên bộ xử lý của bạn là thử chế độ nội suy chất lượng thấp hơn.

3

Tôi biết rằng DirectX được phát hành với Windows 7 được cho là cung cấp khả năng tăng tốc phần cứng 2D. Cho dù điều này ngụ ý nó sẽ đánh bại GDI + về loại hình hoạt động này, tôi không biết. MS có một mô tả khá khó chịu về GDI here có nghĩa là nó chậm hơn so với nó, trong số những thứ khác.

Nếu bạn thực sự muốn tự mình thực hiện loại nội dung này, có một số lớn GDI Tutorial hiển thị nó. Tác giả sử dụng cả SetPixel và "các khối không an toàn", trong các phần khác nhau của hướng dẫn của mình.

Như một sang một bên, đa luồng có thể sẽ giúp bạn ở đây, giả sử máy chủ của bạn có nhiều hơn một CPU. Tức là, bạn có thể xử lý nhiều hơn một hình ảnh cùng một lúc và có thể nhận được kết quả nhanh hơn.

2

Bạn có thể thử

newGrapics.InterpolationMode = InterpolationMode.Low; 

như HighQualityBicubic sẽ là bộ xử lý chuyên sâu của các hoạt động lấy mẫu lại, nhưng tất nhiên sau đó bạn sẽ mất chất lượng hình ảnh nhất.

Ngoài ra, tôi thực sự không thể thấy bất kỳ điều gì có thể được thực hiện để tăng tốc mã của bạn. GDI + gần như chắc chắn là nhanh nhất trên máy Windows (không có mã nào được viết bằng C# sẽ vượt qua thư viện C thuần túy) và việc sử dụng thư viện hình ảnh khác có nguy cơ tiềm ẩn là unsafe và/hoặc mã lỗi.

Điểm mấu chốt là, thay đổi kích thước hình ảnh là một hoạt động tốn kém bất kể bạn làm gì.Giải pháp đơn giản nhất là trường hợp của bạn có thể đơn giản là thay thế CPU của máy chủ bằng mô hình nhanh hơn.

0

Tôi nghi ngờ tăng đột biến là vì bạn có chế độ nội suy được làm quay lên phải. Tất cả các chế độ nội suy đều hoạt động trên mỗi pixel và chất lượng cao BiCubic cao đến mức bạn có thể sử dụng GDI + vì vậy tôi nghi ngờ rằng các phép tính trên mỗi pixel sẽ nhai CPU của bạn.
Khi thử nghiệm, hãy thử giảm chế độ nội suy xuống InterpolationModeNearestNeighbor và xem liệu tăng đột biến CPU - nếu vậy thì đó là thủ phạm của bạn.
Nếu vậy thì làm một số thử và sai cho chi phí vs chất lượng, rất có thể bạn có thể không cần chất lượng Bicubic cao để có được kết quả khá

2

Khi bạn viết

Tôi đã viết một dịch vụ web để thay đổi kích thước người dùng tải lên hình ảnh

Nghe có vẻ như người dùng tải hình ảnh lên máy chủ (web?) và máy chủ sau đó gọi dịch vụ web để thực hiện chia tỷ lệ?

Nếu đúng như vậy, tôi chỉ cần di chuyển tỷ lệ trực tiếp đến máy chủ. Imho, thu nhỏ hình ảnh không biện minh cho dịch vụ web của chính nó. Và bạn nhận được một chút lưu lượng truy cập không cần thiết từ máy chủ đến dịch vụ web và ngược lại. Đặc biệt là vì hình ảnh có thể được mã hóa base64, làm cho lưu lượng dữ liệu lớn hơn.

Nhưng tôi chỉ đoán ở đây.

p.s. Các khối không an toàn trong chính nó không mang lại lợi ích nào, chúng chỉ cho phép biên dịch mã không an toàn. Vì vậy, trừ khi bạn viết định tuyến chia tỷ lệ của riêng bạn, một khối không an toàn sẽ không giúp ích gì.

2

Bạn có thể muốn thử ImageMagick. Nó hoàn toàn miễn phí và cũng có một trình bao bọc .NET: click here. Hoặc here. Hoặc bạn có thể gửi lệnh đến DOS Shell.

Chúng tôi đã sử dụng ImageMagick trên Windows Server bây giờ và sau đó, để xử lý hàng loạt và đôi khi cho một chuyển đổi hình ảnh linh hoạt hơn.

Tất nhiên, cũng có các thành phần thương mại, như các thành phần của Leadtools và Atalasoft. Chúng tôi chưa bao giờ thử những thứ đó.

Các vấn đề liên quan