swimminginthecode DIVE!

Dazz6/ABOUT

고마워써 프로젝트 - #2-5. 연하장 디자인하기

dazz6 2025. 1. 10. 18:00

 

매년 디자인을 설정하는 부분!

여기서는 배경, 썸네일, 글꼴, 글꼴 크기 및 색상까지 페이지를 넘나들며 설정해야 하므로 recoil을 사용했다.

recoil 보러 가기 https://dazz6study.tistory.com/91

 

페이지 초기 접근시 해당 유저가 설정해 둔 정보를 불러와야 하므로 useQuery를 사용했다.

useQuery 보러 가기 https://dazz6study.tistory.com/89

const [design, setDesign] = useRecoilState(ADesignState);

const { isLoading, data } = useQuery<IDesignPost>(
    ["designPost", userId],
    () => DesignPostLoad(userId),
    {
      enabled: designLoad,
      onSuccess: (data) => {
        setDesign({
          designId: data.designId,
          thumbnailPic: data.thumbnailPic,
          thumbnailId: data.thumbnailId,
          backgroundPic: data.backgroundPic,
          backgroundId: data.backgroundId,
          fontId: data.fontId,
          fontSize: data.fontSize,
          fontColor: data.fontColor,
          fontUrl: data.fontUrl,
          fontName: data.fontName,
        });
        setDesignLoad(false);
      },
    }
  );

useQuery가 지원하는 onSuccess를 사용하여 초기값을 세팅하게 만들었다.

 

디자인 배경 및 썸네일은 일러스트레이터를 이용해 직접 디자인했다.

간단하게 150 * 100 사이즈로 여러 컬러 / 분위기를 제공할 수 있도록 노력했다.

예시

 

이미지는 AWS S3 버킷에 업로드했고 해당 링크를 DB에 저장하는 방식으로 사용했다.

 

연하장 내용이 배경 사진 위에 출력되므로 사진에 따라 글씨 색이 자동으로 설정되는 기능을 구현했다.

물론 자동 설정 이후에 사용자가 원하는 색상이 있다면 변경할 수 있다.

 

public String analyzeImage(String imageKey) {
        try {
            if (imageKey.startsWith("http")) {
                imageKey = extractObjectKey(imageKey);
            }

            S3Object s3Object = amazonS3Client.getObject(new GetObjectRequest(bucketName, imageKey));
            InputStream objectData = s3Object.getObjectContent();

            BufferedImage image = ImageIO.read(objectData);
            if (image == null) {
                throw new RuntimeException("이미지를 로드할 수 없습니다.");
            }

            long totalBrightness = 0;
            int width = image.getWidth();
            int height = image.getHeight();
            int totalPixels = width * height;

            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    int rgb = image.getRGB(x, y);

                    int red = (rgb >> 16) & 0xFF;
                    int green = (rgb >> 8) & 0xFF;
                    int blue = rgb & 0xFF;

                    double brightness = 0.299 * red + 0.587 * green + 0.114 * blue;
                    totalBrightness += (long) brightness;
                }
            }

            double averageBrightness = (double) totalBrightness / totalPixels;
            return (averageBrightness > 127.5) ? "bright" : "dark";

        } catch (Exception e) {
            throw new RuntimeException("analyzeImage ERROR : " + e.getMessage(), e);
        }
    }

 

클라이언트에서 imageKey(이미지 링크)를 보내 서버에서 분석한다.

RGB 코드 가중평균방식으로 밝기를 계산한다. (구글링했다... ㅎㅎ)

서버에서 해당 이미지가 밝은지(bright) 어두운지(dark) 반환해 주면,

클라이언트에서 밝은 이미지일 경우 글꼴 색상을 블랙으로 자동 지정해 주는 식이다.