Moja aplikacja pobiera zestaw plików graficznych z sieci i zapisuje je na lokalnym dysku iPhone'a. Niektóre z tych obrazów są dość duże (na przykład szerokość większa niż 500 pikseli). Ponieważ iPhone nie ma nawet wystarczająco dużego wyświetlacza, aby wyświetlić obraz w oryginalnym rozmiarze, planuję zmienić rozmiar obrazu na coś nieco mniejszego, aby zaoszczędzić miejsce / wydajność.
Ponadto niektóre z tych obrazów to pliki JPEG i nie są one zapisywane jako zwykłe 60% ustawienie jakości.
Jak zmienić rozmiar obrazu za pomocą zestawu iPhone SDK i jak mogę zmienić ustawienie jakości obrazu JPEG?
Najłatwiejszym i najprostszym sposobem zmiany rozmiaru obrazów byłoby to
źródło
Powyższe metody działają dobrze w przypadku małych obrazów, ale gdy spróbujesz zmienić rozmiar bardzo dużego obrazu, szybko zabraknie pamięci i zawiesisz aplikację. Znacznie lepszym sposobem jest
CGImageSourceCreateThumbnailAtIndex
zmiana rozmiaru obrazu bez uprzedniego całkowitego dekodowania.Jeśli masz ścieżkę do obrazu, którego rozmiar chcesz zmienić, możesz użyć tego:
Więcej szczegółów tutaj .
źródło
CGImageSource
oprócz obrazów i plików PDF?inSampleSize
używanego przez dekoder Androida. I to jest jedyna odpowiedź, która umożliwia zmniejszenie rozmiaru obrazu w sposób efektywny pod względem pamięci.Najlepszym sposobem skalowania obrazów bez utraty współczynnika kształtu (tj. Bez rozciągania obrazu) jest użycie tej metody:
Dodaj tę metodę do swojej klasy Utility, aby móc jej używać w całym projekcie i uzyskiwać do niej dostęp w następujący sposób:
Ta metoda dba o skalowanie przy zachowaniu proporcji. Dodaje również wcięcia do obrazu w przypadku, gdy pomniejszony obraz ma większą szerokość niż wysokość (lub odwrotnie).
źródło
Jeśli masz kontrolę nad serwerem, zdecydowanie polecam zmianę rozmiaru strony serwera obrazów za pomocą ImageMagik . Pobieranie dużych obrazów i zmiana ich rozmiaru w telefonie to strata wielu cennych zasobów - przepustowości, baterii i pamięci. Wszystkie są rzadkie w telefonach.
źródło
Opracowałem ostateczne rozwiązanie do skalowania obrazu w Swift.
Możesz go użyć do zmiany rozmiaru obrazu w celu wypełnienia, wypełnienia lub dopasowania proporcji do określonego rozmiaru.
Możesz wyrównać obraz do środka lub dowolnej z czterech krawędzi i czterech rogów.
Możesz także przyciąć dodatkową przestrzeń, która jest dodawana, jeśli proporcje oryginalnego obrazu i rozmiaru docelowego nie są równe.
Poniżej przykłady zastosowania tego rozwiązania.
Szary prostokąt to docelowy obraz, do którego zostanie zmieniony rozmiar. Obraz to niebieskie kółka w jasnoniebieskim prostokącie (użyłem kółek, ponieważ łatwo jest zobaczyć, kiedy jest skalowany bez zachowania aspektu). Jasnopomarańczowy kolor oznacza obszary, które zostaną przycięte, jeśli przejdziesz
trim: true
.Dopasowanie proporcji przed i po skalowaniu:
Inny przykład dopasowania aspektu :
Dopasowanie kształtu z wyrównaniem do góry:
Wypełnienie aspektu :
Wypełnij :
W moich przykładach użyłem skalowania w górę, ponieważ łatwiej jest to zademonstrować, ale rozwiązanie działa również w przypadku skalowania w dół, jak w pytaniu.
Do kompresji JPEG powinieneś użyć tego:
Możesz sprawdzić moje sedno z placem zabaw Xcode.
źródło
W przypadku Swift 3 poniższy kod skaluje obraz, zachowując proporcje. Możesz przeczytać więcej o ImageContext w dokumentacji Apple :
Aby z niego skorzystać, wywołaj
resizeImage()
metodę:źródło
możesz użyć tego kodu do skalowania obrazu do wymaganego rozmiaru.
źródło
Zgodnie z tą sesją, iOS Memory Deep Dive , lepiej wykorzystaliśmy
ImageIO
do zmniejszania obrazów.Złe używanie
UIImage
obrazów w niższej skali.Posługiwać się
ImageIO
ImageIO może odczytywać rozmiary obrazów i informacje o metadanych bez zanieczyszczania pamięci.
ImageIO może zmieniać rozmiar obrazów tylko kosztem zmiany rozmiaru obrazu.
O obrazie w pamięci
UIGraphicsBeginImageContextWithOptions
zawsze używaSRGB
formatu renderowania, który wykorzystuje 4 bajty na piksel.load -> decode -> render
3 fazy.UIImage
jest kosztowne w przypadku zmiany rozmiaru i zmiany rozmiaruW przypadku poniższego obrazu, jeśli używasz
UIGraphicsBeginImageContextWithOptions
, potrzebujemy tylko 590 KB do załadowania obrazu, podczas gdy potrzebujemy2048 pixels x 1536 pixels x 4 bytes per pixel
= 10 MB podczas dekodowaniapodczas gdy
UIGraphicsImageRenderer
, wprowadzony w iOS 10, automatycznie wybierze najlepszy format graficzny w iOS12. Oznacza to, że możesz zaoszczędzić 75% pamięci, zastępującUIGraphicsBeginImageContextWithOptions
ją,UIGraphicsImageRenderer
jeśli nie potrzebujesz SRGB.To jest mój artykuł o obrazach iOS w pamięci
lub
źródło
Problem, który może wystąpić na wyświetlaczach Retina, polega na tym, że skala obrazu jest ustawiana przez ImageCapture lub coś podobnego. Powyższe funkcje zmiany rozmiaru tego nie zmienią. W takich przypadkach zmiana rozmiaru nie będzie działać poprawnie.
W poniższym kodzie skala jest ustawiona na 1 (nie skalowana), a zwrócony obraz ma oczekiwany rozmiar. Odbywa się to w trakcie
UIGraphicsBeginImageContextWithOptions
rozmowy.źródło
Dodając do mnóstwa odpowiedzi tutaj, ale wybrałem rozwiązanie, które zmienia rozmiar według rozmiaru pliku, a nie wymiarów.
Zmniejszy to zarówno wymiary, jak i jakość obrazu, dopóki nie osiągnie danego rozmiaru.
Kredyt za skalowanie według rozmiaru odpowiedzi
źródło
Szybka wersja
źródło
Skończyło się na użyciu techniki Brads do stworzenia
scaleToFitWidth
metody,UIImage+Extensions
jeśli jest to przydatne dla kogoś ...wtedy gdziekolwiek chcesz
#import "UIImage+Extensions.h"
UIImage *newImage = [image scaleToFitWidth:100.0f];
Warto również zauważyć, że możesz przenieść to dalej do
UIView+Extensions
klasy, jeśli chcesz renderować obrazy z UIViewźródło
Chciałem tylko odpowiedzieć na to pytanie programistom Cocoa Swift. Ta funkcja zwraca NSImage z nowym rozmiarem. Możesz użyć tej funkcji w ten sposób.
źródło
Jeśli obraz znajduje się w katalogu dokumentów, dodaj to rozszerzenie adresu URL :
Stosowanie:
Uwaga: - Zmień <LocalImagePath.jpg> na lokalną ścieżkę obrazu jpg.
źródło
Jeśli ktoś nadal szuka lepszej opcji
źródło
źródło
Aby zmienić rozmiar obrazu, mam lepsze wyniki (graficzne), używając tej funkcji zamiast DrawInRect:
Proporcje są obsługiwane automatycznie
źródło