쉽게 Figma에서 Android로 이미지 추출하기

MJ Studio
MJ Studio
Published in
10 min readMay 18, 2022

--

보다 좋은 제목이 떠오르지 않는다.

개요

안드로이드는 변화가 있었으나 현재 png 파일로 이미지 에셋을 관리하려면 Screen Density에 따라 총 5개의 파일을 준비하는 것을 기본으로 합니다.

https://developer.android.com/training/multiscreen/screendensities

여기서 유저의 기기의 DPI를 따져 속하는 범위에 해당되는 이미지들을 가져다 씁니다.

우리가 XXXHDPI 기기를 사용하는데 MDPI 폴더에만 어떤 이미지가 존재한다면 안드로이드는 알아서 4배 만큼 키운다음에 사용하는데, 이는 저해상도의 이미지가 나오고 pixel perfection이 되지 못할 가능성이 큽니다.

참고로 그냥 /drawable 폴더에만 넣어두어도 /drawable-mdpi동치입니다.

따라서 우린 5개의 이미지들을 모두 동일한 이름으로 /drawable /drawable-hdpi /drawable-xhdpi /drawable-xxhdpi /drawable-xxxhdpi 에 넣어주어야 하는 대환장쇼를 해야합니다.

제플린같은 경우 이를 잘 지원해줍니다.

피그마는 플러그인들이 있는 것 같긴 합니다만, 플러그인을 사용하려면 프로젝트에 Edit 권한이 있어야 하고 그렇게 유용하지 않던 것으로 기억합니다.

이를 해결하기 위한 쉘 스크립트를 이용한 방법을 소개합니다.

결과물

결과물부터 보여드리면,

대충 우리가 Figma에서 이미지를 export하면 위와 같습니다.

@4x = drawable-xxxhdpi

@3x = drawable-xxhdpi

@2x = drawable-xhdpi

@1.5x = drawable-hdpi

= drawable

우리가 app 모듈의 app/src/main/res/… 폴더의 drawable 폴더들로 이를 옮기고 싶다고 합시다.

쉘 스크립트만 한 번 실행시키면 됩니다.

설정

  1. 다음과 같은 쉘 스크립트를 프로젝트 루트의 icon 폴더에 추가합니다. icon.sh 라는 이름과 icon 이라는 폴더명은 변경하지 않아야 합니다.
#!/bin/bash

CUR_DIR=$(pwd | grep -o '[^/]*$')

if [[ $CUR_DIR != "icon" ]]
then
if [ -d icon ]
then
cd icon
else
echo "[Error] 올바른 스크립트 실행 경로가 아닙니다 프로젝트 루트나 icon 디렉토리에서 bash 로 실행시켜 주세요"
exit 1
fi
fi

MODULE_NAME=$1
if [[ $MODULE_NAME = "" ]]
then
MODULE_NAME="app"
fi
echo "[Info] 모듈 이름은 $MODULE_NAME 입니다"
MODULE_PATH="../$MODULE_NAME"

PATH_MDPI=$MODULE_PATH
PATH_MDPI+='/src/main/res/drawable'
PATH_HDPI=$MODULE_PATH
PATH_HDPI+='/src/main/res/drawable-hdpi'
PATH_XHDPI=$MODULE_PATH
PATH_XHDPI+='/src/main/res/drawable-xhdpi'
PATH_XXHDPI=$MODULE_PATH
PATH_XXHDPI+='/src/main/res/drawable-xxhdpi'
PATH_XXXHDPI=$MODULE_PATH
PATH_XXXHDPI+='/src/main/res/drawable-xxxhdpi'

declare -a MDPI_LIST
declare -a HDPI_LIST
declare -a XHDPI_LIST
declare -a XXHDPI_LIST
declare -a XXXHDPI_LIST

# Create directories if not exists
[ ! -d $PATH_MDPI ] && mkdir -p $PATH_MDPI >/dev/null 2>&1
[ ! -d $PATH_HDPI ] && mkdir -p $PATH_HDPI >/dev/null 2>&1
[ ! -d $PATH_XHDPI ] && mkdir -p $PATH_XHDPI >/dev/null 2>&1
[ ! -d $PATH_XXHDPI ] && mkdir -p $PATH_XXHDPI >/dev/null 2>&1
[ ! -d $PATH_XXXHDPI ] && mkdir -p $PATH_XXXHDPI >/dev/null 2>&1

VALID_ASSET_REGEX="^[a-z_]+(@1.5x|@2x|@3x|@4x)*\.png$"

HDPI_REGEX="@1.5x"
XHDPI_REGEX="@2x"
XXHDPI_REGEX="@3x"
XXXHDPI_REGEX="@4x"

FAILED=false

for f in *.png
do
if [[ $f = "*.png" ]]
then
continue
fi


if [[ $f =~ $VALID_ASSET_REGEX ]]
then
if [[ $f =~ $XXXHDPI_REGEX ]]
then
XXXHDPI_LIST+=($f)
elif [[ $f =~ $XXHDPI_REGEX ]]
then
XXHDPI_LIST+=($f)
elif [[ $f =~ $XHDPI_REGEX ]]
then
XHDPI_LIST+=($f)
elif [[ $f =~ $HDPI_REGEX ]]
then
HDPI_LIST+=($f)
else
MDPI_LIST+=($f)
fi
else # Failed
echo "[Error] $f 는 올바른 이미지 이름이 아닙니다."
FAILED=true
fi
done

if [ $FAILED = true ]
then
exit 1
fi


# Uncomment if need strictly check 5 screen density qualifiers condition

#LEN_MDPI=${#MDPI_LIST[@]}
#LEN_HDPI=${#HDPI_LIST[@]}
#LEN_XHDPI=${#XHDPI_LIST[@]}
#LEN_XXHDPI=${#XXHDPI_LIST[@]}
#LEN_XXXHDPI=${#XXXHDPI_LIST[@]}
#
#if [[ $LEN_MDPI != $LEN_HDPI ]] || [[ $LEN_MDPI != $LEN_XHDPI ]] || [[ $LEN_MDPI != $LEN_XXHDPI ]] || [[ $LEN_MDPI != $LEN_XXXHDPI ]]
#then
# echo "[Error] 어떤 아이콘이 icon 디렉토리에 5개가 준비되어있지 않습니다."
# exit 1
#fi


for f in "${MDPI_LIST[@]}"
do
TMP=$PATH_MDPI
TMP+="/"
TMP+=$f
echo $TMP
mv $f $PATH_MDPI
done

for f in "${HDPI_LIST[@]}"
do
SUFFIX="@1.5x.png"
DEST_FILE_NAME=${f%"$SUFFIX"}
DEST_FILE_NAME+=".png"

DEST_PATH=$PATH_HDPI
DEST_PATH+="/"
DEST_PATH+=$DEST_FILE_NAME

echo $DEST_PATH
mv $f $DEST_PATH
done

for f in "${XHDPI_LIST[@]}"
do
SUFFIX="@2x.png"
DEST_FILE_NAME=${f%"$SUFFIX"}
DEST_FILE_NAME+=".png"

DEST_PATH=$PATH_XHDPI
DEST_PATH+="/"
DEST_PATH+=$DEST_FILE_NAME

echo $DEST_PATH
mv $f $DEST_PATH
done

for f in "${XXHDPI_LIST[@]}"
do
SUFFIX="@3x.png"
DEST_FILE_NAME=${f%"$SUFFIX"}
DEST_FILE_NAME+=".png"

DEST_PATH=$PATH_XXHDPI
DEST_PATH+="/"
DEST_PATH+=$DEST_FILE_NAME

echo $DEST_PATH
mv $f $DEST_PATH
done

for f in "${XXXHDPI_LIST[@]}"
do
SUFFIX="@4x.png"
DEST_FILE_NAME=${f%"$SUFFIX"}
DEST_FILE_NAME+=".png"

DEST_PATH=$PATH_XXXHDPI
DEST_PATH+="/"
DEST_PATH+=$DEST_FILE_NAME

echo $DEST_PATH
mv $f $DEST_PATH
done

2. 안드로이드 스튜디오에서 Shell Script run command를 하나 만듭시다.

위와 같이 대충 만들어주면 됩니다. bash 쉘을 사용하도록 하면 됩니다.

그리고 안드로이드 스튜디오에서 저 커맨드를 실행시킨다면 우리의 쉘 스크립트가 동작합니다.

사용법

피그마에서 이미지를 추출할 때 다음과 같이 5개를 설정하여 추출하면 됩니다. 추출 할 때 icon 디렉토리에 모두 넣어주세요!

굳이 5개가 아니고 그냥 + 버튼만 눌렀을 때 나오는 3x, 2x, 1x 만 추가된 다음에 진행되어도 무방합니다.

중요한 것은 @1.5x @2x @3x @4x 와 같은 suffix와 항상 png 파일이여야 한다는 것 입니다.

그리고 이름에 알파벳 소문자와 언더바, @1.5x 같은 suffix나 .png 이름 이외에 다른 글씨가 들어간다면 안드로이드 에셋 이름을 사용될 수 없기 때문에 에러가 납니다.

이런식으로 실행을 시키면 스크립트가 실행되고 다시 앱을 실행시키고 싶다면

얘로 바꿔준다음에 하면 됩니다.

주의사항

예기치 못한 상황이 발생할 수 있으니 항상 버전 관리 시스템으로 우리의 에셋이 올바르게 올바른 디렉토리에 추가되었는 지 확인해 봅시다. 책임지지 않습니다.

쉘스크립트는 제가 만들었지만 수정과 배포는 자유입니다.

부록

참고로 multi module project를 위해서 shell script에서 인자로 module name을 받을 수 있도록 했는데 알아서 사용하시면 됩니다.

--

--