3

I'm building an app that let you take a picture and remove background (with machine learning).

step 1

Now, when I press "Brightness" button app open a screen where I render gl-react. This is code:

import React, { useRef, useState } from 'react'
import { Shaders, Node, GLSL } from 'gl-react'
import { Surface } from 'gl-react-native'
// ...other imports

type Props = {
  onSave: (uri: string) => void
  uri: string
}

const BrightnessContrast = ({
  onSave,
  uri
}: Props) => {
  const { t } = useTranslation()
  const surfaceRef = useRef<Surface>(null)
  const [contrast, setContrast] = useState(1)
  const [brightness, setBrightness] = useState(1)
  const surfaceStyle = { width: 320, height: 320 }

  const handleOnSaveImage = async () => {
    try {
      const result = await surfaceRef.current?.glView.capture({
        format: 'png'
      })
      const captureUri = result.uri
      if (captureUri) onSave(captureUri)
    } catch (error) {
      // do nothing
    }
  }

  const handleOnCancelImage = () => {
    // code
  }

  const renderBrightnessSlider = () => {
    // code
  }

  const renderContrastSlider = () => {
    // code
  }

  return (
    <Container>
      <Surface ref={surfaceRef} style={surfaceStyle}>
        <Saturate
          {...{
            brightness: brightness,
            contrast: contrast,
            saturation: 1
          }}
        >
          {{ uri }}
        </Saturate>
      </Surface>

      <Footer>
        {renderBrightnessSlider()}
        {renderContrastSlider()}
        <Buttons>
          <IconButton
            backgroundColor={colors.neutralUI5}
            onPress={handleOnCancelImage}
            renderIcon={() => <Close color={colors.white} />}
            text={t('pictureEdit:cancelButton')}
            textColor={colors.white}
          />
          <IconButton
            backgroundColor={colors.gs1Orange}
            onPress={handleOnSaveImage}
            renderIcon={() => <Check color={colors.white} />}
            text={t('pictureEdit:saveButton')}
            textColor={colors.white}
          />
        </Buttons>
      </Footer>
    </Container>
  )
}

const shaders = Shaders.create({
  Saturate: {
    frag: GLSL`
  precision highp float;
  varying vec2 uv;
  uniform sampler2D t;
  uniform float contrast, saturation, brightness;
  const vec3 L = vec3(0.2125, 0.7154, 0.0721);
  void main() {
    vec4 c = texture2D(t, uv);
      vec3 brt = c.rgb * brightness;
      gl_FragColor = vec4(mix(
      vec3(0.5),
      mix(vec3(dot(brt, L)), brt, saturation),
      contrast), c.a);
  }`
  }
})

interface SaturationProps {
  brightness: number
  children: React.ReactNode
  contrast: number
  saturation: number
}

const Saturate = ({
  brightness,
  children,
  contrast,
  saturation
}: SaturationProps) => (
  <Node
    shader={shaders.Saturate}
    uniforms={{ contrast, saturation, brightness, t: children }}
  />
)

export { BrightnessContrast }

and this is screenshot:

step 2

When I save for the first time all works fine (another screenshot)

step 3

but when I try to reopen Brightness screen gl-react show me a pixelated border.

step 4

The strange thing is that this pixelated border disappear when I save picture again. It appears to be visible only during rendering (last screenshot).

step 5

What could it be? Shaders? Picture have png format and background removal service it is not 100% perfect so I can have parts of picture that seems to be transparent but they are not

UPDATE: I tried to edit shader replacing c.a with 0.5 and borders disappear but I have other issues. I think update shader could be the right way.

  precision highp float;
  varying vec2 uv;
  uniform sampler2D t;
  uniform float contrast, saturation, brightness;
  const vec3 L = vec3(0.2125, 0.7154, 0.0721);
  void main() {
      vec4 c = texture2D(t, uv);
      vec3 brt = c.rgb * brightness;
      gl_FragColor = vec4(mix(
      vec3(0.5),
      mix(vec3(dot(brt, L)), brt, saturation),
      contrast), 0.5); <--- HERE
  }
Carmelo Catalfamo
  • 93
  • 1
  • 4
  • 15
  • Maybe a premultiplied alpha problem: https://stackoverflow.com/questions/39341564/webgl-how-to-correctly-blend-alpha-channel-png – LJᛃ Oct 08 '21 at 15:08
  • Is this pixelated border after cancellation or after confirmation? – Ali Yaghoubi Oct 14 '21 at 10:14
  • @AliYaghoby after confirm. The new image is created by gl-react and it looks good when I render it as an but when I try to render again on gl-react I can see pixelated border – Carmelo Catalfamo Oct 14 '21 at 10:43
  • 1
    This is because you are trying to adjust several **Brightness** steps. Try setting values such as **Brightness** or **Contrast** to Global. – Ali Yaghoubi Oct 14 '21 at 10:48
  • @AliYaghoby This is a great starting point. I may have 2 images: the original and the edited one. When the user save the image I can show the edited one. When the user wants to change again the brightness I could show the original image with the previous brightness value (saved on the store or somewhere). When user save new brightness I update "edited image". – Carmelo Catalfamo Oct 14 '21 at 13:37

0 Answers0