Jak zmienić rozmiar obrazu za pomocą SwiftUI?

109

Mam duży obraz w Assets.xcassets. Jak zmienić rozmiar tego obrazu za pomocą SwiftUI, aby był mały?

Próbowałem ustawić ramkę, ale to nie działa:

Image(room.thumbnailImage)
    .frame(width: 32.0, height: 32.0)
subdan
źródło

Odpowiedzi:

238

Powinieneś użyć .resizable()przed zastosowaniem jakichkolwiek modyfikacji rozmiaru na Image.

Image(room.thumbnailImage)
    .resizable()
    .frame(width: 32.0, height: 32.0)
rraphael
źródło
6
Jak zmienić rozmiar obrazu, zachowując proporcje?
Mark Kang,
1
@MarkKang Nie próbowałem, ale jest metoda o nazwieaspectRatio(_:contentMode:)
rraphael
4
Image („image01”) .resizable () .aspectRatio (UIImage (o nazwie: „image01”) !. size, contentMode: .fit)
Mark Kang
1
To byłoby miłe. Ale myślę, że jest błąd z dopasowaniem. hackingwithswift.com/swiftui/…
Mark Kang
18
Image("name").resizable().scaledToFit()nie jest jednak zbugowany. Możesz więc zawinąć obraz w widoku, dostosować ramkę widoku do dowolnego wymaganego rozmiaru, a scaledToFit()następnie sprawić, by obraz był tak duży, jak to tylko możliwe, zachowując proporcje.
jemmons,
43

Co powiesz na to:

struct ResizedImage: View {
    var body: some View {

            Image("myImage")
                .resizable()
                .scaledToFit()
                .frame(width: 200.0,height:200)

    }
}

widok obrazu ma wymiary 200x200, ale obraz zachowuje oryginalne proporcje (przeskalowanie w ramach tej klatki)

Zdezorientowany Vorlon
źródło
To rozwiązanie nie zachowuje w moim przypadku oryginalnych proporcji.
pooya,
@ pm89 jaki rozmiar ma Twój oryginalny i ostateczny obraz / widok?
Confused Vorlon
1
Oryginalny współczynnik proporcji to 3/2, a wynik to 1/1, co powoduje rozciągnięcie obrazu. Wygląda na to, że jest to błąd w SwiftUI. Skończyło się na metodzie sugerowanej przez Marka Kanga w komentarzach pod zaakceptowaną odpowiedzią, Image(uiImage: image!).resizable().aspectRatio(image!.size, contentMode: .fill)gdzie imagejest typu, UIImageponieważ Imagetyp nie ujawnia żadnej właściwości size.
pooya,
Dla mnie to działa tak, łącznie z zachowaniem proporcji, dzięki 👍
laka
To zachowuje dla mnie proporcje, ale nie uwzględnia rozmiaru - tj. Nie otrzymuję kwadratowego obrazu.
Chris Prince,
19

Rozwinięcie odpowiedzi i komentarzy @ rraphael:

Począwszy od Xcode 11 beta 2, możesz skalować obraz do dowolnych wymiarów, zachowując oryginalne proporcje, zawijając obraz w inny element.

na przykład

struct FittedImage: View
{
    let imageName: String
    let width: CGFloat
    let height: CGFloat

    var body: some View {
        VStack {
            Image(systemName: imageName)
                .resizable()
                .aspectRatio(1, contentMode: .fit)
        }
        .frame(width: width, height: height)
    }
}


struct FittedImagesView: View
{
    private let _name = "checkmark"

    var body: some View {

        VStack {

            FittedImage(imageName: _name, width: 50, height: 50)
            .background(Color.yellow)

            FittedImage(imageName: _name, width: 100, height: 50)
            .background(Color.yellow)

            FittedImage(imageName: _name, width: 50, height: 100)
            .background(Color.yellow)

            FittedImage(imageName: _name, width: 100, height: 100)
            .background(Color.yellow)

        }
    }
}

Wyniki

Dopasowane obrazy z zachowaniem proporcji

(Z jakiegoś powodu obraz jest nieco rozmyty. Możesz mieć pewność, że rzeczywisty obraz jest ostry).

Womble
źródło
Prawdopodobnie widzisz rozmyty obraz na SO, ponieważ używasz monitora o wysokiej rozdzielczości. Umieściłem to na monitorze o zwykłym DPI i wygląda ostro
Ben Leggiero,
2
Zachowuje to oryginalny współczynnik proporcji tylko dlatego, że współczynnik proporcji oryginalnego obrazu wynosi 1 (obraz jest kwadratowy) i używasz .aspectRatio(1, .... Nie mówię, że jak dotąd inne rozwiązanie zadziałało dla mnie ...
pooya
15

W SwiftUI użyj .resizable()metody, aby zmienić rozmiar obrazu. Używając .aspectRatio()i określając a ContentMode, możesz odpowiednio „Dopasować” lub „Wypełnić” obraz.

Na przykład, oto kod, który zmienia rozmiar obrazu przez dopasowanie:

Image("example-image")
.resizable()
.aspectRatio(contentMode: .fit)
amp.dev
źródło
3
struct AvatarImage: View {
    var body: some View {

            Image("myImage")
                .resizable()
                .scaledToFill() // <=== Saves aspect ratio
                .frame(width: 60.0, height:60)
                .clipShape(Circle())

    }
}
Amarshan
źródło
3

Uwaga: Moja nazwa obrazu to img_Logoi możesz zmienić nazwę obrazu zdefiniować właściwości obrazu w ten sposób:

 VStack(alignment: .leading, spacing: 1) {
                        //Image Logo Start
                        Image("img_Logo")
                            .resizable()
                            .padding(.all, 10.0)
                            .frame(width: UIScreen.main.bounds.width * 0.4, height: UIScreen.main.bounds.height * 0.2)
                        //Image Logo Done
                    }
cmlcrn17
źródło
Gorąco polecam napisanie krótkiego tekstu wraz z kodem, jakieś wyjaśnienie. Zapoznaj się z kodeksem postępowania tutaj: stackoverflow.com/conduct
disp_name
3

Innym podejściem jest użycie scaleEffectmodyfikatora:

Image(room.thumbnailImage)
    .resizable()
    .scaleEffect(0.5)
Luis Fer Garcia
źródło
2

Jeśli chcesz użyć proporcji przy zmianie rozmiaru, możesz użyć następującego kodu:

Image(landmark.imageName).resizable()
                .frame(width: 56.0, height: 56.0)
                .aspectRatio(CGSize(width:50, height: 50), contentMode: .fit)
dinesh sharma
źródło
2

Ponieważ nie powinniśmy kodować / naprawiać rozmiaru obrazu. Oto lepszy sposób na zapewnienie zakresu dostosowanego do rozdzielczości ekranu na różnych urządzeniach.

Image("ImageName Here")
       .resizable()
       .frame(minWidth: 60.0, idealWidth: 75.0, maxWidth: 95.0, minHeight: 80.0, idealHeight: 95.0, maxHeight: 110.0, alignment: .center)
       .scaledToFit()
       .clipShape(Capsule())
       .shadow(color: Color.black.opacity(5.0), radius: 5, x: 5, y: 5)
Hanny
źródło
2

Domyślnie widoki obrazów automatycznie dopasowują się do ich zawartości, co może spowodować, że wyjdą poza ekran. Jeśli dodasz modyfikator resizable (), obraz zostanie automatycznie dopasowany tak, aby wypełniał całą dostępną przestrzeń:

Image("example-image")
    .resizable()

Jednak może to również spowodować zniekształcenie oryginalnego współczynnika kształtu obrazu, ponieważ zostanie rozciągnięty we wszystkich wymiarach o dowolną wielkość potrzebną do wypełnienia przestrzeni.

Jeśli chcesz zachować współczynnik proporcji, dodaj modyfikator AspectRatio, używając .fill lub .fit, na przykład:

Image("example-image")
    .resizable()
    .aspectRatio(contentMode: .fit)
sudan suwal
źródło
1

Jeśli chcesz zmienić rozmiar obrazu w swiftUI, użyj następującego kodu:

import SwiftUI

    struct ImageViewer : View{
        var body : some View {
            Image("Ssss")
            .resizable()
            .frame(width:50,height:50)
        }
    }

Ale tutaj jest z tym problem. Jeśli dodasz ten obraz do przycisku, obraz nie będzie wyświetlany, tylko blok koloru niebieskiego będzie tam. Aby rozwiązać ten problem, po prostu zrób to:

import SwiftUI

struct ImageViewer : View{
    var body : some View {
        Button(action:{}){
        Image("Ssss")
        .renderingMode(.original)
        .resizable()
        .frame(width:50,height:50)
    }
   }
}
sachin jeph
źródło
1

Możesz zdefiniować właściwości obrazu w następujący sposób: -

   Image("\(Image Name)")
   .resizable() // Let you resize the images
   .frame(width: 20, height: 20) // define frame size as required
   .background(RoundedRectangle(cornerRadius: 12) // Set round corners
   .foregroundColor(Color("darkGreen"))      // define foreground colour 
Komal Gupta
źródło
1

Bardzo ważne jest zrozumienie logicznej struktury kodu. Podobnie jak w SwiftUI, rozmiar obrazu nie jest domyślnie zmieniany. W związku z tym, aby zmienić rozmiar dowolnego obrazu, należy nadać mu możliwość zmiany rozmiaru, stosując modyfikator .resizable () natychmiast po zadeklarowaniu widoku obrazu.

Image("An Image file name")
    .resizable()
Shawkath Srijon
źródło