티스토리 뷰

 

저는 항상 오픈소스를 만들고 찾아다니는 것을 즐깁니다. 어릴 때는 다른 사람들이 어떻게 코드를 짜는지에 대한 단순한 호기심으로 시작했습니다. 그때는 제 실력이 부족하다고 생각해서 기여할 생각은 없었지만, 지금은 어느 정도 실력이 있다고 자부하면서 프론트엔드 관련 오픈소스를 개발하고 유지보수하고 있었습니다. (이건 제가 좋아서 하는 것입니다.)

최근에 제가 애용하던 VSCode 확장 프로그램인 Material Icon Theme에서 Flutter 폴더에 대한 아이콘이 제공되지 않는다는 것을 깨달았습니다. 저는 Flutter에 대해 애정이 많습니다. Flutter는 제가 모바일 앱 개발에 첫발을 디딜 수 있게 해준 매우 고마운 프레임워크입니다. 상태 관리와 렌더링, 트리 구조에 대한 이해, 최적화 기법 등 다양한 지식들을 저에게 안겨다줬었죠. (그만큼 저에겐 소중한 존재입니다. 꼬옥)

그래서 평소에 snippet, dev와 같은 폴더 아이콘이 없는 것에 불만을 가지고 있었는데, Flutter 관련 폴더에 아이콘을 지원하지 않는 이 괴심한(?) Material Icon Theme에 기여라도 하고 싶었습니다. 이것은 마치 전장에 깃발을 꽂는 행위랑 거의 같았죠. 🤣

 

 

Material Icon Theme With VSCode

 

이어서 Material Icon Theme 깃허브 저장소를 포크하고 PR을 했는데, SVG에 대한 그리드 시스템 도입으로 인해 아이콘의 왠만하면 플롯한 아이콘의 경우 path 위치 값이 픽셀 그리드(pixels grid)에 맞아야 한다는 피드백을 받았습니다.

픽셀 그리드를 나타내는 간단한 예시 이미지

이 피드백의 이유는 매우 간단합니다.

디스플레이의 최소 단위는 픽셀입니다. 1픽셀은 흔히 디스플레이의 소자 1개를 의미하며, 제 미래의 아내라고도 볼 수 있는 Flutter에서는 이를 'logical pixels'라고 부릅니다. 디스플레이에서 소자의 중간을 표현하는 것은 물리적으로 불가능합니다. 소자가 이동하지 않기 때문에 중간 값을 표현하려면 이를 별도로 보간(보정)하여 표현하는 수밖에 없습니다.

 

앞서 설명했던 이러한 과정에서 흐릿함이 유발되는 것입니다. 래스터화(Rasterization) 과정에서 원래 1픽셀로 표현되어야 할 부분이 2픽셀로 표현되고, 그것을 보정하기 위해서 경계선 부분이 최대한 1픽셀로 표현될 수 있도록 흐릿하게 처리됩니다. (안티엘리어싱과 동일하거나 비슷합니다.) 이는 이미지를 표현하는 경우에도 마찬가지입니다.

 

큰 이미지를 작은 이미지로 표현하는 과정에서 오차가 발생할 수 밖에 없기 때문에 추가적인 보정으로 이미지 화질을 개선합니다, 2픽셀이 1픽셀로 표현되어야 하기 때문이죠, 따라서 이를 보정하는 엔진도 당연히 성능이 뛰어나야 합니다.

 

브라우저를 예로 들면, 크롬의 경우 가장 흐릿하게 표현되고 픽셀도 많이 깨집니다. 하지만 파이어폭스의 경우 크롬보다 이미지 보정과 SVG 표현력이 매우 뛰어나죠. 이것은 단순히 제 개인적인 생각일 수 있겠지만 2024년을 기준으로 두 브라우저를 자주 사용하는 사람이라면 대부분은 저처럼 느낄 것입니다.


따라서 단순히 이미지 화질이 뛰어나다고 해서 항상 선명하게 보이는 것은 아니라는 것을 알 수 있죠. 다만 이미지 크기가 크면 상대적으로 정확한 보간이 가능한 환경이 조성되어 더 선명해 보일 수 있긴 합니다. (그리고 손실 압축된 이미지가 많이 깨진 상태라 하더라도 화질이 높으면 그게 덜해보이기 때문에 더더욱 그렇습니다.)

 

제가 앞서 설명한 문제를 해결하는 기법은 흔히 'SVG Grid System' 또는 'Pixel Perfect'라고 불립니다. 개발에서 그리드는 보통 일정한 행과 열을 의미하죠.

 

가이드라인에 맞춰 최대한 아이콘을 구성하는 요소들의 위치와 크기를 맞추는 것입니다, 그게 너무 힘들고 조금은 정확하게 표현되게 하려면 앞서 설명했듯이 모든 위치와 크기를 정수로 정의하는 방법도 존재합니다.

 

결과적으로는 이런 사소한 과정을 거치지 않고 아이콘을 제작하게 된다면 위 이미지에서 본 것처럼 차이가 좀 많이 심하게 날 수 있습니다, 물론 당연하게도 좋은 장점은 물론 나쁜 단점도 역시 존재합니다.

 

사용자가 이미지를 확대할 때는 정확한 이미지를 보여줄 수 없다는 것입니다, 정확한 위치 값을 정의할 수 없어서죠. (실수를 정수로 나타내면 오차가 발생하는 것과 같습니다.)


이 기여를 통해 배운 점은, 오픈소스 프로젝트에서는 단순히 기능 추가뿐만 아니라 코드 품질과 유지보수성, 사용자 경험 등 여러 가지를 고려해야 한다는 것입니다. 이런 피드백을 통해 더 나은 품질의 기여를 할 수 있었고, 앞으로도 계속해서 오픈소스 커뮤니티에 기여하고자 하는 의욕이 더욱 커졌습니다.

개인적으로, 오픈소스에 기여함으로써 다른 사람과 소통하며 새로운 기법과 기술을 배우고 같이 현업하는 방법을 배움으로서, 제 자신이 성장해가는 것을 느끼는 것은 마치 신이 된 것보다 더 큰 기쁨을 선사해주는 것 같습니다.

따라서 거만해지지 말고, 더 이상 배울 게 없다고 투덜대지 말고, 사용자에게 더 나은 환경을 제공하기 위해 항상 노력해야겠다는 것을 다시 한번 실감하게 해주는 하루였습니다.

 

이 글을 읽어주셔서 감사합니다.

 

 

Added folder-icon for flutter by MTtankkeo · Pull Request #2511 · material-extensions/vscode-material-icon-theme

Description Added folder-icon for google flutter framework. Contribution Guidelines By creating this pull request, I acknowledge that I have read the Contribution Guidelines for this project. ...

github.com