Проблема обрезки с помощью Metal Shader для CIKernel ⇐ IOS
-
Anonymous
Проблема обрезки с помощью Metal Shader для CIKernel
Я разрабатываю шейдер для рендеринга изображения с эффектом кадра кинопленки. Я создал следующий шейдер:
extern "C" { пространство имен coreimage { float4 reassemble(источник сэмплера, кадр сэмплера, float imgWidth, float perFrameSize, float epsilon, пункт назначения) { координата float2 = dest.coord(); float4 srcExtent = source.extent(); пиксель float4 = float4(0, 1, 0, 1); floatsideFrameSize = epsilon + (imgWidth - srcExtent.z)/2 - perFrameSize; смещение с плавающей запятой =sideFrameSize + perFrameSize - эпсилон; если (coord.x = offset && coord.x = srcExtent.z + offset + perFrameSize - epsilon) { пиксель = source.sample(source.transform(float2(coord.x + srcExtent.x - srcExtent.z - смещение - perFrameSize + epsilon, coord.y))); } float4framePixel =frame.sample(frame.transform(coord)); return mix(pixel,framePixel,framePixel.a); } } } Он работает как положено и создает следующее изображение.
Проблема возникает при попытке интегрировать сбор урожая в конвейер. Когда я добавляю обрезку перед вызовом функции ядра, все работает как положено. Однако если я обрежу выходное изображение с помощью функции ядра, окажется, что сначала обрезается исходное изображение, а затем шейдер запускается на обрезанном изображении.
if let source = self.kernel.apply(extent:frameImage.extent, roiCallback: { _, rect -> CGRect в возврат прямоугольника }, аргументы: [scaled.transformed(by: .init(translationX: 0, y: perFrameWidth - vOffset)),frameImage, image.extent.width, perFrameWidth, hOffset]) { return source.cropped(to:frameImage.extent.insetBy(dx: 80, dy: 200)) } Результирующее изображение, созданное с помощью приведенного выше кода.
Хотя это могла бы быть оптимизация, она довольно неожиданная. Как изменить это поведение, чтобы гарантировать, что выходное изображение шейдера будет обрезано, а не исходное? Мы будем очень признательны за ваши идеи.
Я хотел бы объяснить этот вопрос более подробно. Первым аргументом шейдера является изображение, и важно отметить, что я не обрезаю его напрямую. Вместо этого обрезка происходит на выходном изображении. Как ни странно, изображение, которое я передаю в шейдер, тоже кажется обрезанным. Более того, я пытаюсь обрезать изображение после вызывающего шейдера, и странно, что шейдер получает обрезанное изображение.
Исходное изображение
Выходное изображение без обрезки
Выходное изображение с обрезкой
Я разрабатываю шейдер для рендеринга изображения с эффектом кадра кинопленки. Я создал следующий шейдер:
extern "C" { пространство имен coreimage { float4 reassemble(источник сэмплера, кадр сэмплера, float imgWidth, float perFrameSize, float epsilon, пункт назначения) { координата float2 = dest.coord(); float4 srcExtent = source.extent(); пиксель float4 = float4(0, 1, 0, 1); floatsideFrameSize = epsilon + (imgWidth - srcExtent.z)/2 - perFrameSize; смещение с плавающей запятой =sideFrameSize + perFrameSize - эпсилон; если (coord.x = offset && coord.x = srcExtent.z + offset + perFrameSize - epsilon) { пиксель = source.sample(source.transform(float2(coord.x + srcExtent.x - srcExtent.z - смещение - perFrameSize + epsilon, coord.y))); } float4framePixel =frame.sample(frame.transform(coord)); return mix(pixel,framePixel,framePixel.a); } } } Он работает как положено и создает следующее изображение.
Проблема возникает при попытке интегрировать сбор урожая в конвейер. Когда я добавляю обрезку перед вызовом функции ядра, все работает как положено. Однако если я обрежу выходное изображение с помощью функции ядра, окажется, что сначала обрезается исходное изображение, а затем шейдер запускается на обрезанном изображении.
if let source = self.kernel.apply(extent:frameImage.extent, roiCallback: { _, rect -> CGRect в возврат прямоугольника }, аргументы: [scaled.transformed(by: .init(translationX: 0, y: perFrameWidth - vOffset)),frameImage, image.extent.width, perFrameWidth, hOffset]) { return source.cropped(to:frameImage.extent.insetBy(dx: 80, dy: 200)) } Результирующее изображение, созданное с помощью приведенного выше кода.
Хотя это могла бы быть оптимизация, она довольно неожиданная. Как изменить это поведение, чтобы гарантировать, что выходное изображение шейдера будет обрезано, а не исходное? Мы будем очень признательны за ваши идеи.
Я хотел бы объяснить этот вопрос более подробно. Первым аргументом шейдера является изображение, и важно отметить, что я не обрезаю его напрямую. Вместо этого обрезка происходит на выходном изображении. Как ни странно, изображение, которое я передаю в шейдер, тоже кажется обрезанным. Более того, я пытаюсь обрезать изображение после вызывающего шейдера, и странно, что шейдер получает обрезанное изображение.
Исходное изображение
Выходное изображение без обрезки
Выходное изображение с обрезкой
Мобильная версия