Najlepsza praktyka - obsługa obrazów na stronie internetowej

9

Przesyłam starą stronę eCommerce do MVC 3 i chciałbym skorzystać z ulepszeń projektu. Witryna ma obecnie obrazy produktów przechowywane w 3 rozmiarach: miniaturowym, średnim (do wyświetlenia na liście) i rozwiniętym dla powiększonego wyglądu. W tej chwili musimy przesłać 3 osobne obrazy o dokładnie dopasowanym rozmiarze, podać 3 różne nazwy, które pasują do oczekiwań witryny itp., To jest ból.

Chciałbym przesłać tylko 1 plik, duży, a następnie pozwolić stronie zmniejszyć go do potrzebnych rozmiarów, i chciałbym mieć swobodę zmiany rozmiaru miniatury i listy w zależności od preferencji użytkownika, formatu (np. Na telefon komórkowy, iPada , pulpit) itp., więc może potrzebować wielu kopii tego samego obrazu. Moje pytanie brzmi: czy obraz powinien zostać zmniejszony, a następnie zapisany kilka razy po przesłaniu, a jeśli tak, jaka jest dobra konwencja przechowywania / nazewnictwa?

Innym pomysłem jest przechowywanie tylko jednego obrazu, ale programowa zmiana jego wielkości przed podaniem go klientowi. Czy ktoś to zrobił i jakie są wady oprócz kilku kolejnych cykli maszynowych? W jaki sposób przekazujesz klientowi tymczasowy obraz w pamięci (nie ma adresu URL)?

Steve
źródło

Odpowiedzi:

13

Jestem głównym programistą dla brytyjskiej firmy turystycznej. Jednym z wdrożonych przeze mnie projektów była internetowa wersja naszej biblioteki obrazów, do której można automatycznie wyszukiwać zdjęcia z naszej witryny. Zawiera około 150 tys. Zdjęć, z których około 60–70 tys. Jest dostępnych na stronie (najwyżej ocenione).

Zaczęliśmy od zdefiniowania około 5 rozmiarów, stworzenia tych wersji rozmiarów w locie i przechowywania ich w Amazon S3. Cena była minimalna, ale Amazon jest tak skonstruowany, aby z wdziękiem zawodził, więc często widzieliśmy brakujące obrazy. Im bardziej rozwinęliśmy naszą stronę, tym bardziej nienawidziliśmy posiadania tylko pięciu rozmiarów obrazu.

Przeszliśmy do modelu dynamicznej zmiany rozmiaru, w którym możemy dodawać parametry szerokości i / lub wysokości do identyfikatora URI dowolnego obrazu, aby renderować go w tym rozmiarze w locie. Przechowujemy w pamięci podręcznej obraz o zmienionym rozmiarze (używając skrótu MD5 identyfikatora URI żądania jako nazwy pliku).

Aby uzyskać obraz nr 12345 (nasze obrazy są pobierane za pośrednictwem bazy danych, ale można zastąpić je ścieżką do pliku) o szerokości 200 i jakości jpg 80%, format URI byłby następujący:

http://images.domain.com/?imageid=12345&w=200&q=80

To rozwiązanie było łatwe do wdrożenia i działa bezproblemowo - nie ma zauważalnego opóźnienia dla odwiedzających witrynę, nawet na stronach zawierających 20-30 zdjęć.

Robimy to wszystko z .net, chociaż napisałem również skrypt zmiany rozmiaru obrazu PHP, który robi to samo.

Mam nadzieję, że to pomaga, Adam

Adam
źródło
Zabawne jest dla mnie to, że „przewidywanie zmiany rozmiaru” jest tak naprawdę formą buforowania - po prostu niezwykle prymitywną i ograniczoną. Buforowanie po pierwszym żądaniu jest zwykłym podejściem i - zwykle - lepszym. Wyjątkiem jest sytuacja, w której w przeciwnym razie masz do czynienia z ogromnymi ilościami danych naraz , co prawdopodobnie nie ma tutaj miejsca.
Aaronaught
Brilliant @Adam (to moja najlepsza znajomość w Wielkiej Brytanii), dziękuję za przemyślany post. Odpadam.
Steve
2

ImageProcessor ImageProcessor

Imageprocessor to lekka, rozszerzalna biblioteka napisana w C #, która pozwala na manipulowanie obrazami w locie za pomocą .NET

Zmiana rozmiaru w locie:

<!--Automatic height based on width-->
http://your-image?width=600
<!--Automatic width based on height-->
http://your-image?height=250
<!--Both dimensions specified-->
http://your-image?width=600&height=250
<!--Both dimensions specified with the image anchored to the top-->
http://your-image?width=600&height=250&anchor=top
<!--Height ratio passed for automatic scaling-->
http://your-image?width=600&heightratio=0.416
<!--Width ratio passed for automatic scaling-->
http://your-image?widthratio=2.4&height=250
<!--Background color added to padded image-->
http://your-image?width=600&height=250&bgcolor=fff  

ImageProcessor.Web jest standardowo wyposażony w buforowanie . Każdy przetworzony obraz jest asynchronicznie buforowany zarówno w przeglądarce, jak i na serwerze przez wybrany przez Ciebie czas. Pamięć podręczna serwera inteligentnie przechowuje miliony obrazów i po cichu aktualizuje się, gdy oryginalny obraz ulegnie zmianie lub pamięć podręczna wygasa.

Soren
źródło
1

Zakładając, że miniatura jest po prostu przeskalowaną wersją głównego obrazu, myślę, że należy to zrobić w czasie przesyłania, ale być może zaplanowane jako zadanie w tle, aby nie wpływać na inne procesy. Jeśli zmieniasz rozmiar w locie, pamiętaj o buforowaniu obrazu.

Najważniejsze w tym wszystkim jest to, że najlepszą miniaturą dla niektórych obrazów nie jest zwykła zmiana rozmiaru wzorca; konieczne może być powiększanie i kadrowanie w sposób sterowany przez człowieka. Możesz chcieć wykonać automatyczną zmianę rozmiaru, ale masz mechanizm, który pozwala na przesłonięcie w tych szczególnych przypadkach.

Peter Rowell
źródło
0

Niewielka różnica w tym, o czym wspomniał Adam:

(1) utwórz niestandardową stronę błędu (reguła dla obrazów)

(2) Struktura nazw plików obrazów powinna być:

ImageId_Width_Height_Quality

Jedynym wyjątkiem jest oryginalny obraz, który powinien mieć nazwę:

ImageId_Original

(3) Po przesłaniu pliku, np .: 1245_Original -> wszystkie pliki z 1245_ * powinny zostać usunięte

(4) Niestandardowa strona błędu (zakładając, że 1245_Original Exists) powinna dynamicznie tworzyć żądany plik obrazu, np .:

1245_250_400_80.jpg

i też podajcie to za pierwszym razem.

W efekcie przesłanie nowego obrazu powoduje wyczyszczenie pamięci podręcznej.

Ciemna noc
źródło