UIImage и UIimage.pngData возвращают два разных изображения

MRE

import SwiftUI

struct SwiftUIView: View {
    
    func maskImage(image: UIImage, mask: UIImage) -> UIImage {
        let imageReference = image.cgImage!
        let maskReference = mask.cgImage!

        let width = maskReference.width
        let height = maskReference.height
        let bitsPerComponent = maskReference.bitsPerComponent
        let bitsPerPixel = maskReference.bitsPerPixel
        let bytesPerRow = maskReference.bytesPerRow

        let context = CGContext(
            data: nil,
            width: width,
            height: height,
            bitsPerComponent: bitsPerComponent,
            bytesPerRow: bytesPerRow,
            space: CGColorSpaceCreateDeviceGray(),
            bitmapInfo: CGImageAlphaInfo.none.rawValue
        )

        context!.draw(maskReference, in: CGRect(x: 0, y: 0, width: width, height: height))

        let maskImage = context!.makeImage()!

        let maskedReference = imageReference.masking(maskImage)!

        return UIImage(cgImage: maskedReference)
    }
    
    var body: some View {
        VStack {
            Image(uiImage: maskImage(image: UIImage(named: "uni")!, mask: UIImage(named: "mask")!))
                .background(.red)
            
            Image(uiImage: UIImage(data: maskImage(image: UIImage(named: "uni")!, mask: UIImage(named: "mask")!).pngData()!)!)
                .background(.red)
        }
    }
}

Этот код маскирует изображение и возвращает UIImage

Вы можете видеть в VStack, что первое изображение правильное. Он показывает маскированное изображение с красным фоном за маскируемой областью.

На втором изображении VStack видно, что прозрачность исчезла.

Итак, что мне нужно сделать, это загрузить temp.pngData() на сервер и ожидать, что я смогу просмотреть файл png с сохраненной прозрачностью, как показано в коде предварительного просмотра. Но вместо этого, когда файл загружается, я получаю оригинал без прозрачности.

Как исправить?

temp.pngData() дает вам Optional, вы должны развернуть его перед использованием в UIImage(data: temp.pngData()). Подсказка: используйте ! так же, как вы неправильно используете везде в своем коде.
workingdog support Ukraine 01.07.2023 02:46

@workingdogsupportUkraine ничем не отличается от !

erotsppa 01.07.2023 04:14

Я действительно удивлен, что вы можете скомпилировать код, который вы показываете, без использования !, например: Image(uiImage: UIImage(data: temp.pngData()!)!).

workingdog support Ukraine 01.07.2023 04:34

@workingdogsupportUkraine вы правы, я сделал это менее запутанным, вставив MRE

erotsppa 01.07.2023 04:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Обе версии кода, которые вы показываете, недействительны.

maskImage() не является допустимым вызовом вашей функции. Вы не передаете изображение или второе изображение, чтобы замаскировать его. Это даже не должно компилироваться.

Даже если вы вызовете функцию maskImage(image:mask:) с изображением и маской, она вернет изображение, сериализованное в формате PNG, а это не то же самое, что UIImage.

Наконец, вы не говорите, что вы делаете с вашим UIImage или данными PNG из вашего изображения, поэтому мы не можем сказать, что вы подразумеваете под «это не сработает».

спасибо, я обновил вопрос с дополнительной информацией

erotsppa 30.06.2023 23:54
Ответ принят как подходящий

Вы должны сделать другое изображение из замаскированного изображения, если вам нужно объединенное изображение, такое как PNG:

let renderer = UIGraphicsImageRenderer(size: maskedImage.size)
let newImage = renderer.image { _ in maskedImage.draw(at: .zero) }

Теперь замаскированная область удалена, и вы можете использовать newImage.pngData() как положено.

Также обратите внимание, что вы можете объединить эту логику (а не этот код) с .turnedNotPureBlackIntoBlack()! (из вашего другого вопроса), когда вы раскрашиваете новое изображение маски.

Mojtaba Hosseini 03.07.2023 13:14

Другие вопросы по теме