2010-02-10 21 views
22

công ty của tôi gần đây đã bắt đầu để có được vấn đề với các xử lý cho các trang web của chúng tôi hình ảnh.hình ảnh Phục vụ với on-the-fly thay đổi kích thước

Chúng tôi có một số trang web (giải trí người lớn) mà hình ảnh hiển thị như bìa đĩa dvd, ảnh chụp nhanh và tương tự. Chúng tôi có khoảng 100 nghìn bộ phim và mỗi bộ phim chúng tôi có trung bình 30 ảnh chụp nhanh + bìa. Hầu như mọi hình ảnh đều có phiên bản bổ sung với làm mờ và che phủ cho những người không phải thành viên, điều này dẫn đến khoảng 50 hình ảnh cho mỗi bộ phim hoặc tổng cộng 5 triệu hình ảnh cơ bản. Mỗi phòng trong số các hình ảnh có sẵn trong một số phiên bản, tùy thuộc vào nơi nó được đặt trên trang (thumbnail, ban đầu, xem trước nhỏ, xem trước không quá nhỏ, hình ảnh nhỏ trong top-list, vv) mà kết quả trong hình ảnh hơn tôi quan tâm để đếm.

Bây giờ tôi đã có ý tưởng sử dụng máy chủ để tạo ảnh trực tiếp vì nó trở nên khá vụng về để tạo tất cả các hình ảnh khác nhau cho tất cả các trang khác nhau (vì các trang khác nhau đôi khi thậm chí cần kích thước hình ảnh khác nhau về cơ bản cùng một nhiệm vụ).

Có ai biết của một máy chủ xử lý hình ảnh có thể giảm quy mô hình ảnh on-the-fly vì vậy chúng tôi chỉ cần cung cấp những hình ảnh ban đầu và những kẻ web chỉ có thể yêu cầu bất cứ điều gì kích thước mà họ cần?

Yêu cầu:

  • hiệu suất rất cao (vài ngàn người dùng mỗi ngày)
  • On-the-fly mờ và lớp phủ tạo
  • On-the-fly thay đổi kích thước (có và không có tỉ lệ giữ)
  • có thể xử lý hàng triệu hình ảnh
  • phải có khả năng đọc định dạng JPG, GIF, PNG và BMP và chuyển đổi giữa chúng

Bảo mật không phải là mối quan tâm nhiều như hình ảnh không bị mờ có thể đạt được bằng thao tác URL và bảo mật hơn sẽ tốt đẹp nhưng không bắt buộc và thẳng thắn tôi ngừng chăm sóc (Sau khi không vào được đồng nghiệp của tôi, tại sao (cho trang người bán lại nhỏ của chúng tôi) nên sử dụng http://example.com/view_image.php?filename=/data/images/01020304.jpg để hiển thị hình ảnh).

Chúng tôi đã thử PHP kịch bản để làm điều này nhưng việc thực hiện còn quá chậm đối với nhiều người sử dụng này.

Cảm ơn trước cho bất cứ đề nghị bạn có.

+0

https://github.com/willnorris/imageproxy – wildloop

Trả lời

26

Tôi khuyên bạn nên thiết lập máy chủ web chuyên dụng để xử lý thay đổi kích thước hình ảnh và phân phối kết quả cuối cùng. Tôi đã làm một cái gì đó tương tự, mặc dù trên một quy mô nhỏ hơn nhiều. Về cơ bản nó loại bỏ quá trình kiểm tra cache.

Nó hoạt động như thế này:

  • bạn yêu cầu hình ảnh phụ thêm kích thước yêu cầu để tên tập tin như http://imageserver/someimage.150x120.jpg
  • nếu hình ảnh tồn tại, nó sẽ được trả lại không có chế biến khác (đây là điểm chính , kiểm tra bộ nhớ cache là ẩn)
  • nếu hình ảnh không tồn tại, xử lý 404 không tìm thấy qua .htaccess và định tuyến lại yêu cầu đến tập lệnh tạo hình ảnh có kích thước yêu cầu
  • trong tập lệnh chỉ định danh sách kích thước được phép để tránh các cuộc tấn công như kịch bản yêu cầu tất cả các kích thước có thể phải đóng cửa máy chủ của bạn xuống
  • giữ này trên một miền không có cookie để giảm thiểu lưu lượng không cần thiết

EDIT: Tôi không nghĩ rằng PHP chính nó sẽ làm chậm quá trình này nhiều, như PHP scripting trong trường hợp này được giảm đến mức tối thiểu: việc chia tỷ lệ hình ảnh được thực hiện bởi một thư viện nội trang được viết bằng C. Dù bạn làm gì, bạn sẽ phải sử dụng một thư viện như thế này (GD hoặc libmagick hay như vậy) để không thể tránh khỏi. Với hệ thống của tôi ít nhất bạn hoàn toàn bỏ qua chi phí kiểm tra bộ nhớ cache, do đó làm giảm thêm sự tương tác PHP. Bạn có thể thực hiện điều này trên máy chủ hiện tại của mình, vì vậy tôi đoán đó là giải pháp phù hợp với ngân sách của bạn.

+0

Đề xuất tốt, tôi sẽ kiểm tra xem có thể triển khai điều này mà không cần thêm máy chủ web vì chúng tôi không thể có được một cái cho việc này hay không. – dbemerlin

+0

Đó là hoàn toàn có thể, tôi đề nghị các máy chủ chuyên dụng chỉ để chia sẻ tải. Trong bất kỳ trường hợp nào, ngay cả trên một máy chủ đơn lẻ, hãy cân nhắc sử dụng một máy chủ ảo khác cho điểm cuối cùng mà tôi đã đề cập –

+0

Tôi chấp nhận giải pháp này vì nó có vẻ là giải pháp tốt nhất với chi phí thấp nhất, bây giờ tôi chỉ cần có thông qua quản lý. – dbemerlin

7

Dựa trên

Chúng tôi đã thử các script PHP để làm điều này nhưng việc thực hiện còn quá chậm đối với nhiều người sử dụng này.

Tôi sẽ giả sử bạn không lưu trong bộ nhớ cache kết quả. Tôi khuyên bạn nên lưu vào bộ nhớ cache các hình ảnh kết quả trong một hoặc hai ngày (ví dụ: hãy kiểm tra tập lệnh của bạn để xem hình thu nhỏ đã được tạo chưa, nếu sử dụng nó, nếu nó chưa tạo ra nó).

Điều này sẽ cải thiện hiệu suất đáng kể khi tôi tưởng tượng trang chính/trang bắt đầu có thể có nhiều lượt truy cập hơn so với video X ngẫu nhiên, do đó khi xem trang chính không có hình ảnh nào được tạo khi được lưu trong bộ nhớ cache. Khi Người dùng Y xem Phim X, họ sẽ không nhận thấy độ trễ nhiều vì nó chỉ cần tạo một trang đó.

Đối với khía cạnh "Thay đổi kích thước nhanh" - mức độ quan trọng của băng thông đối với bạn như thế nào?Tôi muốn giả sử bạn đang trải qua rất nhiều phim với một vài kb thêm hình ảnh cho mỗi yêu cầu sẽ không làm hại quá nhiều. Nếu trường hợp đó xảy ra, bạn chỉ có thể sử dụng hình ảnh lớn hơn và đặt chiều rộng và chiều cao và để cho trình duyệt thực hiện mở rộng quy mô cho bạn.

+4

Thậm chí tốt hơn so với bộ nhớ đệm chúng tại địa phương ... Yêu cầu hình ảnh thông qua một CDN và sau đó CDN sẽ cache tất cả các tạo hình ảnh cho bạn và phục vụ chúng nhanh hơn bạn có thể, với chi phí băng thông rẻ hơn. Đó là cách chúng tôi làm điều đó và nó cực kỳ hiệu quả. –

+0

+1 Tôi hoàn toàn thứ hai! Tại sao thiết lập một máy chủ đắt tiền khi bạn cần có thể đạt được những gì bạn cần với các công cụ gia đình. –

+0

@Greg Beech: rất khó để tìm thấy một CDN mà sẽ được hạnh phúc để cache các loại tập tin. – cherouvim

4

Các ImageCacheImage Exact Sizes giải pháp từ Drupal cộng đồng có thể làm được điều này, và giống như hầu hết các giải pháp phần mềm nguồn mở sử dụng các thư viện từ ImageMagik

Có một số hình ảnh AMI cho dịch vụ Amazon EC2 để làm hình ảnh rộng. Nó sử dụng S3 của Amazon để lưu trữ hình ảnh, ban đầu và vảy, và có thể đưa chúng qua dịch vụ CDN Amazon (Cloud Front). Kiểm tra trên trang EC2 về những gì có sẵn

Một tùy chọn khác là Google. Tài liệu của Google hiện hỗ trợ tất cả các loại tệp, vì vậy bạn có thể tải hình ảnh lên thư mục tài liệu Google và chia sẻ thư mục để truy cập công khai. URL của loại dài, ví dụ:

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I

Thêm tham số = s để chia tỷ lệ hình ảnh, tuyệt! ví dụ. cho 200 pixel rộng

http://lh6.ggpht.com/VMLEHAa3kSHEoRr7AchhQ6HEzHVTn1b7Mf-whpxmPlpdrRfPW216UhYdQy3pzIe4f8Q7PKXN79AD4eRqu1obC7I=s200

Google chỉ phí 5 USD/năm cho 20GB. Có một API đầy đủ cho tài liệu tải lên vv

câu trả lời khác về vấn đề SO How best to resize images off-server

+0

Cảm ơn bạn đã đề xuất tốt nhưng nhà cung cấp bên ngoài là (đáng buồn) không phải là một lựa chọn (quản lý sẽ không chấp nhận nó, chúng tôi đã cố gắng để có được một cái gì đó tương tự thông qua) – dbemerlin

+0

gợi ý tốt đẹp! Kỹ thuật này có thể được sử dụng để hỗ trợ chiều cao và chiều rộng chính xác không? \ – DjangoRocks

1

Ok đầu tiên được rằng thay đổi kích thước một hình ảnh với bất kỳ ngôn ngữ mất một thời gian xử lý ít. Vậy làm thế nào để bạn hỗ trợ hàng ngàn khách hàng? Chúng tôi sẽ lưu vào bộ nhớ cache để bạn chỉ phải tạo hình ảnh một lần. Lần tới, ai đó yêu cầu hình ảnh đó, hãy kiểm tra xem nó đã được tạo chưa, nếu nó vừa trả lại. Nếu bạn có nhiều máy chủ ứng dụng thì bạn sẽ muốn lưu vào bộ nhớ cache vào hệ thống tệp trung tâm để tăng tỷ lệ truy cập bộ nhớ cache và giảm dung lượng cần thiết. Để lưu trữ bộ nhớ cache đúng cách, bạn cần phải sử dụng quy ước đặt tên có thể dự đoán có tính đến tất cả các cách khác nhau mà bạn muốn hiển thị hình ảnh của mình, tức là sử dụng một cái gì đó như myimage_blurred_320x200.jpg để lưu jpeg bị mờ và thay đổi kích thước thành Chiều rộng 300 và 200, vv ..

Cách tiếp cận khác là ngồi máy chủ hình ảnh của bạn phía sau máy chủ proxy theo cách tất cả logic bộ nhớ đệm được thực hiện tự động cho bạn và hình ảnh của bạn được phục vụ bởi máy chủ web nhanh.

Bạn sẽ không thể phục vụ hàng triệu hình ảnh được định lại kích thước theo bất kỳ cách nào khác. Đó là cách Google và Bing tạo bản đồ, chúng tạo trước tất cả các hình ảnh mà chúng cần cho thế giới ở các khoảng cách được đặt trước khác nhau để chúng có thể cung cấp hiệu suất phù hợp và có thể trả về các ảnh tĩnh được tạo trước.

Nếu php quá chậm, bạn nên xem xét sử dụng thư viện đồ họa 2D từ Java hoặc .NET vì chúng rất phong phú và có thể hỗ trợ tất cả các yêu cầu của bạn. Để có được một hương vị của API đồ họa ở đây là một phương pháp trong .NET sẽ thay đổi kích thước bất kỳ hình ảnh nào thành chiều rộng hoặc chiều cao mới được chỉ định. Nếu bạn bỏ qua chiều cao hoặc chiều rộng, nó sẽ thay đổi kích thước duy trì tỷ lệ khung hình phù hợp. Lưu ý Hình ảnh có thể được tạo từ JPG, GIF, PNG hoặc BMP:

// Creates a re-sized image from the SourceFile provided that retails the same aspect ratio of the SourceImage. 
// - If either the width or height dimensions is not provided then the resized image will use the 
//  proportion of the provided dimension to calculate the missing one. 
// - If both the width and height are provided then the resized image will have the dimensions provided 
//  with the sides of the excess portions clipped from the center of the image. 
public static Image ResizeImage(Image sourceImage, int? newWidth, int? newHeight) 
{ 
    bool doNotScale = newWidth == null || newHeight == null; ; 

    if (newWidth == null) 
    { 
     newWidth = (int)(sourceImage.Width * ((float)newHeight/sourceImage.Height)); 
    } 
    else if (newHeight == null) 
    { 
     newHeight = (int)(sourceImage.Height * ((float)newWidth)/sourceImage.Width); 
    } 

    var targetImage = new Bitmap(newWidth.Value, newHeight.Value); 

    Rectangle srcRect; 
    var desRect = new Rectangle(0, 0, newWidth.Value, newHeight.Value); 

    if (doNotScale) 
    { 
     srcRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height); 
    } 
    else 
    { 
     if (sourceImage.Height > sourceImage.Width) 
     { 
      // clip the height 
      int delta = sourceImage.Height - sourceImage.Width; 
      srcRect = new Rectangle(0, delta/2, sourceImage.Width, sourceImage.Width); 
     } 
     else 
     { 
      // clip the width 
      int delta = sourceImage.Width - sourceImage.Height; 
      srcRect = new Rectangle(delta/2, 0, sourceImage.Height, sourceImage.Height); 
     } 
    } 

    using (var g = Graphics.FromImage(targetImage)) 
    { 
     g.SmoothingMode = SmoothingMode.HighQuality; 
     g.InterpolationMode = InterpolationMode.HighQualityBicubic; 

     g.DrawImage(sourceImage, desRect, srcRect, GraphicsUnit.Pixel); 
    } 

    return targetImage; 
} 
+0

Cảm ơn các gợi ý và mã, tôi sẽ kiểm tra nó và kiểm tra xem nó có đủ nhanh không (và tôi cũng sẽ tạo một chuẩn PHP để kiểm tra xem đồng nghiệp đã đúng với "PHP quá chậm"). – dbemerlin

0

Nếu mỗi hình ảnh khác nhau được nhận dạng duy nhất bằng một URL thì tôi chỉ cần sử dụng CDN như AKAMAI. Hãy để kịch bản PHP của bạn thực hiện công việc và để AKAMAI xử lý tải.

Vì loại doanh nghiệp này thường không có vấn đề về ngân sách, đó sẽ là nơi duy nhất tôi xem xét.

Chỉnh sửa: chỉ hoạt động nếu bạn tìm thấy CDN sẽ phân phối loại nội dung này cho bạn.

+0

Tôi phải loại bỏ giải pháp này vì ngân sách có sẵn chính xác là 0 Euro (hoặc cho bạn là người Hoa Kỳ: chính xác là $ 0). Chúng tôi thậm chí không thể quản lý để phê duyệt cài đặt một máy chủ thử nghiệm hoặc phát triển (nhưng bây giờ chúng tôi mất gấp đôi thời gian để phát triển là không có vấn đề bởi vì các nhà phát triển chi phí không có gì như họ đã có ...). Tuy nhiên, cảm ơn đề nghị của bạn. – dbemerlin

+0

Máy chủ hình ảnh chuyên dụng VÀ mạng CND có thể hoạt động tốt với nhau. Bạn sẽ được tải đi fro trang web chính của bạn và những hình ảnh vẫn sẽ được phân phối rất nhanh trên toàn cầu. – adrianTNT

1

Trong thời gian câu hỏi này đã được hỏi, một vài công ty đã nổi lên để giải quyết vấn đề chính xác này. Nó không phải là một vấn đề được cô lập cho bạn hoặc công ty của bạn. Nhiều công ty đạt đến điểm mà họ cần tìm một giải pháp lâu dài hơn cho nhu cầu xử lý hình ảnh của họ.

Các dịch vụ như imgix đóng vai trò là proxy và CDN cho các hoạt động hình ảnh như thay đổi kích thước và áp dụng lớp phủ. Bằng cách thao tác URL, bạn có thể áp dụng các phép biến đổi khác nhau cho mỗi hình ảnh. imgix phục vụ hàng tỷ yêu cầu mỗi ngày.

Bạn cũng có thể tự mình thực hiện các dịch vụ và đặt chúng sau một CDN. Các dự án mã nguồn mở như imageproxy là tốt cho việc này. Điều này đặt gánh nặng bảo trì cho nhóm hoạt động của bạn.

(Disclaimer:. Tôi làm việc cho imgix)

1

gì bạn đang tìm kiếm là lần xuất hiện tốt nhất bằng Thumbor http://thumbor.readthedocs.org/en/latest/index.html, đó là mã nguồn mở, được hỗ trợ bởi một công ty khổng lồ (có nghĩa là nó sẽ không biến mất vào ngày mai), và tàu với rất nhiều tính năng đẹp như phát hiện những gì quan trọng trên một hình ảnh khi cắt xén.

Với CDN chi phí thấp, tôi khuyên bạn nên kết hợp nó với bộ nhớ Cloudfront và AWS hoặc giải pháp có thể so sánh với CDN miễn phí như Cloudflare. Đây có thể không phải là nhà cung cấp CDN hoạt động tốt nhất, nhưng ít nhất vẫn hoạt động tốt hơn một máy chủ và cũng giảm tải máy chủ hình ảnh của bạn với giá rẻ. Thêm vào đó, nó sẽ giúp bạn tiết kiệm được một TON chi phí băng thông.

0

Vấn đề chính xác này hiện đang được giải quyết bằng các dịch vụ thay đổi kích thước hình ảnh dành riêng cho tác vụ này. Họ cung cấp các tính năng sau:

  1. Trong xây dựng CDN - bạn không cần phải lo lắng về việc phân phối hình ảnh
  2. hình ảnh thay đổi kích thước một cách nhanh chóng - bất kỳ kích thước cần thiết có sẵn
  3. Không lưu trữ cần thiết - bạn chỉ cần hình ảnh cửa hàng cơ sở và tất cả các các biến thể được xử lý bởi dịch vụ
  4. Thư viện hệ sinh thái - bạn chỉ có thể bao gồm javascript và công việc của bạn được thực hiện cho tất cả các thiết bị và tất cả các trình duyệt.

Một dịch vụ như vậy là Gumlet. Bạn cũng có thể thử một số thay thế nguồn mở như plugin nginx mà cũng có thể thay đổi kích thước hình ảnh trên bay.

(Tôi làm việc cho Gumlet.)

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