본문 바로가기
flutter/Widget of the Week

Flutter[플러터] / ImageFiltered를 사용하여 이미지에 효과 및 필터 적용 시키기 (BackdropFillter, 흐리게, 블러, 모자이크 처리, 변형, ImageFilter) ImageFiltered (Flutter Widget of the Week)

by ch5c 2025. 7. 20.
반응형

ImageFiltered class

자식에 ImageFilter를 적용합니다.

이미지 필터는 항상 자식 위젯에 필터 연산을 적용합니다. 이는 해당 필터가 개념적으로 "no-op"인 경우(예: 반경이 0인 ImageFilter.blur 또는 단위행렬을 갖는 ImageFilter.matrix)에도 마찬가지입니다. ImageFiltered.enabled를 로 설정하면 false이미지 필터를 비활성화하는 데 더 효율적입니다.

https://youtu.be/7Lftorq4i2o

공식 문서 코드

 


우리가 이미지를 사용할 때 그 이미지에 블러를 먹여 모자이크 처리를 하고나 다른 효과를 줘야 할 때가 있다. 이럴 때 어떻게 해야 할까? 뭐 다른 디자인 프로그램에서 이미지에 효과를 다 줄다음 그것을 사용해도 되겠지만 여기 ImageFilltered 위젯을 사용하면 손쉽게 이미지에 여러 효과를 줄 수 있게 된다.

ImageFiltered 위젯은 그 생성자들을 사용하여 이미지나 자식 위젯에 그래픽 필터 효과를 적용할 수 있게 해주는 위젯인데 기본적인 사용법을 알아보고 생성자들에 대해서 알아보자.

 

사용하는 방법은 간단하다. 자신이 효과를 먹이고 싶은 이미지 위젯을 ImageFiltered 위젯으로 감싸주면 된다.

ImageFiltered(
  child: Image.network(
    'https://docs.flutter.dev/assets/images/dash/Dash.png',
  ),
)

이제 이런 후 효과를 이제 먹여줘야 하는데 imageFilter 파라미터를 사용해 주면 된다. 이 파라미터에 들어가는 위젯은 ImageFilter라는 위젯인데 기본적으로 이 ImageFilter 위젯은 자체만으로는 사용이 불가능하고 반드시 생성자를 붙여야만 사용이 가능하다.

ImageFiltered(
  imageFilter: ImageFilter(), // 단독으로 사용 불가
  child: Image.network(
    'https://docs.flutter.dev/assets/images/dash/Dash.png',
  ),
)

이제 한번 ImageFilter 위젯의 생성자에 따른 효과와 사용법 대해서 알아보자.

ImageFilter.blur

가장 흔하게 사용되는 생성자로 이미지에 가우시안 블러를 적용해 줄 수 있다.

imageFilter: ImageFilter.blur(),

이제 이 상태로 실행하게 되면 블러라 해놓고 아무 효과도 적용이 안된 모습을 볼 수 있다.

그 이유로는 블러 값을 직접 먹여줘야 하기 때문인데 sigmaX, sigmaY 파라미터를 사용해 주면 된다.

두 파라미터 모두 double 타입을 받는데 먼저 sigmaX에 값을 줘보겠다.

imageFilter: ImageFilter.blur(
  sigmaX: 5,
),

X축(가로)을 기준으로 블러가 먹어진 것을 알 수 있다. 근데 이것 만으로는 뭔가 화면이 흔들리는 것만 같지 블러가 먹여진 것 같진 않다. 이제 Y축(세로)도 값을 먹여준다면 제대로 블러가 먹여지는 모습을 확인할 수 있을 것이다.

imageFilter: ImageFilter.blur(
  sigmaX: 5,
  sigmaY: 5
),

이렇게 손쉽게 블러 효과를 먹여줄 수 있게 된다. (또한 당연하지만 값을 높이면 블러 효과도 더 강해진다.)

ImageFilter.dilate

ImageFilter.dilate 생성자는 픽셀 채널 값을 주변 반경 내에서 최댓값으로 확장하는 효과를 가지고 있다. 쉽게 말해 이미지를 부풀리는 듯한 시각적 효과를 낼 수 있게 해 준다. 일단 마찬가지로 사용해 주자.

imageFilter: ImageFilter.dilate(),

이제 방금 위에서 봤다시피 이 상태에서는 실행은 된다마는 아무런 효과가 주어져 있지 않은 상태이다. 이번에는 radiusXradiusY 파라미터를 사용하여 효과를 주자. 바로 둘 다 사용해 주겠다.

imageFilter: ImageFilter.dilate(
  radiusX: 3,
  radiusY: 3
),

이렇게 보이는 것처럼 각 픽셀 채널(R/G/B/A)을 주어진 x, y 반경 내에서 최댓값으로 확장해 주는 효과를 가지고 있다. 값을 좀 더 올려보면 아래와 같이 나타나게 된다.

imageFilter: ImageFilter.dilate(
  radiusX: 15,
  radiusY: 15
),

radiusX radiusY는 각각 수평, 수직으로 확장할 픽셀 반경을 나타내준다.

값이 커질수록 더욱 뚜렷하게 테두리가 퍼지는 듯한 효과가 나타나게 된다.

ImageFilter.erode

이 생성자는 방금 본 ImageFilter.dilate 생성자의 반대 버전이라고 생각하면 편하다. ImageFilter.dilate 생성자는 픽셀을 확장시켰다 이 ImageFilter.erode 생성자는 픽셀을 축소시켜 주는 효과를 가지고 있다. 일단 마찬가지로 기본은 똑같다.

imageFilter: ImageFilter.dilate(),

이제 여기에서 파라미터도 ImageFilter.dilate 생성자와 같은데 radiusX radiusY를 가지고 있다. 다만 이제 아까랑 효과가 정반대인 것뿐이다. 근데 값 적게 넣으니 너무 불쾌한 골짜기 마냥 이미지가 변해 버려서 바로 높은 값을 넣어놨다;;

imageFilter: ImageFilter.erode(
  radiusX: 8,
  radiusY: 8
),

ImageFilter.dilate는 하얀색이 강조되는 반변에 ImageFilter.erode는 그 반대로 검은색이 강조되는 모습이다.

ImageFilter.matrix

ImageFilter.matrix 생성자는 4x4행렬을 이용해 자식 위젯의 시각 효과(변환)를 만들 수 있는 필터다.

이 필터는 생긴 거 그대로 Matrix위젯을 사용하기 때문에 스케일, 회전, 이동, 기울이기 같은 시각 변형을 다 일으킬 수 있다.

근데 자신이 천재라면 Matrix위젯을 사용하지 않고 기본값인 4x4 행렬을 나타내는 Float64List를 그대로 사용해 주면 된다.

imageFilter: ImageFilter.matrix(
  Float64List.fromList([
    1, 0.3, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1,
  ])
),

근데 우린 천재가 아니니 Matrix 클래스를 사용해서 만들어주자.

바로 Matrix4 클래스를 사용해 주면 되는데 자세한 내용은 다른 문서를 참고해 주길 바란다.

imageFilter: ImageFilter.matrix(
  Matrix4.skewY(0.2).storage,
),

암튼 원하는 함수(현재 코드에서는 skewY)를 호출했다면 그 뒤에 생성자로 storage를 사용해 마무리해 주면 간단하게 기울여줄 수 있다.

당연하지만 기울기도 넣어줄 수 있다. 마찬가지로 storage 생성자를 호출해 마무리해주면 된다.

imageFilter: ImageFilter.matrix(
  Matrix4.rotationZ(0.2).storage,
),

애초에 Matrix 클래스를 사용하기 때문에 솔직히 생성자 이름을 transform으로 만드는 게 맞지 않았나 생각이 든다..

ImageFilter.compose

ImageFilter.compose는 두 개의 ImageFilter를 합성(composite)하여 순차적으로 적용할 수 있도록 해주는 생성자인데 쉽게 말해 우리가 위에서 줬던 효과를 중복 적용시킬 수 있다는 말이다.

파라미터는 outeriner, 이 두 개로 구성되어 있는데 outer 파라미터는 먼저 적용될 필터값을 나타내고 iner은 나중에 적용될 필터값을 나타내준다.

한번 블러효과 + 기울기 조합으로 만들어보겠다.

imageFilter: ImageFilter.compose(
  outer: ImageFilter.matrix(Matrix4.skewY(0.2).storage),
  inner: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
),

여기서 굉장히 중요하고 알아 둬야 할 것은 outeriner 파라미터의 실행 순서이다. 말했다시피 outer가 먼저 실행되고 iner가 후에 실행되게 되는데 현재 코드에서는 먼저 기울인 후에 블러를 먹여서 이미지에 효과가 잘 적용된 모습이지만 이러한 순서를 무시하고 코드를 막자면 아래와 같이 된다.

imageFilter: ImageFilter.compose(
  outer: ImageFilter.blur(sigmaX: 5, sigmaY: 5),
  inner: ImageFilter.matrix(Matrix4.skewY(0.2).storage)
),

outer에 블러를 넣음으로써 효과가 먼저 적용되게 되었고 그로 인해 현재 기울어지기 전의 상태인 구역까지 블러 처리가 되어 버린 모습이다. 암튼 ImageFilter.compose 생성자는 이 순서만 유의하면서 사용해 주면 된다.

ImageFilter.shader

마지막으로 알아볼 생성자는 ImageFilter.shader 생성자로 ShaderImageFilter로 변환해 자식 위젯에 적용할 수 있게 해 준다. 즉 직접 Shader로 만든 그라디언트나 이미지 패턴을 필터처럼 사용할 수 있게 해 준다는 말이다.

다만 ImageFilter.shader는 아직 공식적으로 사용 가능한 API로 노출되지 않아서 문서에 나와 있더라도 실제로는 Flutter SDK 내부 비공개 또는 실험적 API에 해당하여 현재 stable 채널에서는 사용이 불가능하다. 

 

암튼 이렇게 ImageFiltered 위젯의 사용법에 대해 알아보았는데 다른 방식으로 필터를 먹일 수 있는 BackdropFilter 위젯의 상위 호환 격 위젯이기 때문에 거의 이미지에 효과를 줘야 할 땐 필수로 사용될 것 같다. 도움이 되었길 바라며 마치겠다.

반응형