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)

Odpowiedzi:


238

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

Image(room.thumbnailImage)
    .resizable()
    .frame(width: 32.0, height: 32.0)

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)


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).


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)

3

Cóż, wydaje się to całkiem proste w SwiftUI / Po pokazie, które dali: https://developer.apple.com/videos/play/wwdc2019/204

struct RoomDetail: View {
     let room: Room
     var body: some View {

     Image(room.imageName)
       .resizable()
       .aspectRatio(contentMode: .fit)
 }

Mam nadzieję, że to pomoże.


3
struct AvatarImage: View {
    var body: some View {

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

    }
}

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
                    }

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)

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)

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)

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)

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)
    }
   }
}

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 

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()
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.