Skip to content

Commit

Permalink
[이미지 리사이즈]
Browse files Browse the repository at this point in the history
  • Loading branch information
hoban4336 committed Jun 12, 2024
1 parent ea8558e commit 9868617
Show file tree
Hide file tree
Showing 11 changed files with 204 additions and 46 deletions.
100 changes: 96 additions & 4 deletions src/main/java/com/aptner/v3/attach/service/AttachService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

import static com.aptner.v3.global.error.ErrorCode._NOT_FOUND;
import static com.aptner.v3.global.util.MultipartUtil.createFileId;
import static com.aptner.v3.global.util.MultipartUtil.createKey;
import static com.aptner.v3.global.util.MultipartUtil.*;

@Slf4j
@Service
Expand All @@ -41,8 +45,22 @@ public Attach upload(AttachType type, MultipartFile file) {
String uuid = createFileId();
String key = createKey(type.getLocation(), uuid, file.getContentType());

// s3
String url = s3Service.uploadFile(key, file);
// 원본 데이터
MultipartFile resizedFile = resizeImage(file, 1200); // 원하는 크기로 조정
String url = s3Service.uploadFile(key, resizedFile);

// ThumbNail 데이터 ( 나눔 장터 )
resizedFile = resizeImage(file, 300); // 원하는 크기로 조정
String thumb_url = s3Service.uploadFile(
createThumbKey(type.getLocation(), uuid, "300", file.getContentType())
, resizedFile);

// Middle 데이터 (Qna)
resizedFile = resizeImage(file, 600); // 원하는 크기로 조정
String middle_url = s3Service.uploadFile(
createThumbKey(type.getLocation(), uuid, "600", file.getContentType())
, resizedFile);
log.debug("url : {}, thumb_url : {}, middle_url : {}", url, thumb_url, middle_url);

// db
Attach attach = Attach.builder()
Expand Down Expand Up @@ -95,4 +113,78 @@ public String getUrl(String uuid) {
private String getKeyfromAttach(Attach attach) {
return createKey(attach.getType().getLocation(), attach.getUuid(), attach.getContentType());
}

private MultipartFile resizeImage(MultipartFile originalFile, int targetWidth) {
try {
// MultipartFile을 BufferedImage로 변환
BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(originalFile.getBytes()));

// 원본 이미지의 비율 계산
int originalWidth = originalImage.getWidth();
int originalHeight = originalImage.getHeight();
int targetHeight = (int) ((double) targetWidth / originalWidth * originalHeight);

// 이미지 리사이즈
Image resizedImage = originalImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH);

// 리사이즈된 이미지를 BufferedImage로 변환
BufferedImage bufferedResizedImage = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
bufferedResizedImage.getGraphics().drawImage(resizedImage, 0, 0, null);

// 원본 파일의 확장자 가져오기
String originalFilename = originalFile.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);


// BufferedImage를 ByteArrayOutputStream으로 변환
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bufferedResizedImage, extension, baos);
byte[] resizedBytes = baos.toByteArray();

// 리사이즈된 이미지를 MultipartFile로 변환
return new MultipartFile() {
@Override
public String getName() {
return originalFile.getName();
}

@Override
public String getOriginalFilename() {
return originalFile.getOriginalFilename();
}

@Override
public String getContentType() {
return originalFile.getContentType();
}

@Override
public boolean isEmpty() {
return resizedBytes.length == 0;
}

@Override
public long getSize() {
return resizedBytes.length;
}

@Override
public byte[] getBytes() throws IOException {
return resizedBytes;
}

@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(resizedBytes);
}

@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
Files.write(dest.toPath(), resizedBytes);
}
};
} catch (IOException e) {
throw new RuntimeException("Failed to resize image", e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ public ApiResponse<?> getPost(
BoardGroup boardGroup = getBoardGroup();
T post = commonPostService.getPost(boardGroup, postId, user.toDto().getId());
post.setReactionType(commonPostService.getPostReactionType(user.toDto().getId(), postId));
return ResponseUtil.ok((S) post.toResponse());
return ResponseUtil.ok((S) post.toResponseWithComment());
}

@PostMapping("/")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@
import com.aptner.v3.member.Member;
import com.aptner.v3.member.dto.MemberDto;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import jakarta.validation.constraints.*;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.*;
import lombok.experimental.SuperBuilder;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static com.aptner.v3.board.common_post.dto.CommonPostCommentDto.organizeChildComments;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toMiddleSizeImageUrl;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toThumbSizeImageUrl;

@Slf4j
@Getter
Expand Down Expand Up @@ -95,7 +100,7 @@ public CommonPostResponse toResponse() {
// post
.title(isSecret ? blindTitle : dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toThumbSizeImageUrl(dto))
.visible(dto.isVisible())
// post info
.hits(dto.getHits()) // 조회수
Expand Down Expand Up @@ -134,13 +139,13 @@ public CommonPostResponse toResponseWithComment() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toMiddleSizeImageUrl(dto))
.visible(dto.isVisible())
.comments(organizeChildComments(dto.getCommentDto()))
// .comments(organizeChildComments(dto.getCommentDto()))
// post info
.hits(dto.getHits()) // 조회수
.reactionColumns(isSecret ? null : dto.getReactionColumnsDto()) // 공감
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments()) // 댓글 수
// category
.boardGroup(dto.getBoardGroup())
Expand Down Expand Up @@ -241,6 +246,45 @@ public static boolean isNew(CommonPostDto dto) {
return dto.getCreatedAt().isAfter(fortyEightHoursAgo);
}

}
public static List<String> toMiddleSizeImageUrl(CommonPostDto dto) {
if (dto.getImageUrls() == null) return null;

List<String> resizedUrls = new ArrayList<>();
for (String url : dto.getImageUrls()) {
if (containsValidImageExtension(url)) {
String baseUrl = url.substring(0, url.lastIndexOf("."));
String extension = url.substring(url.lastIndexOf("."));
resizedUrls.add(baseUrl + "/600" + extension);
} else {
resizedUrls.add(url); // 원본 데이터 반환
}
}
return resizedUrls;
}

public static List<String> toThumbSizeImageUrl(CommonPostDto dto) {
if (dto.getImageUrls() == null) return null;

List<String> resizedUrls = new ArrayList<>();
for (String url : dto.getImageUrls()) {
if (containsValidImageExtension(url)) {
String baseUrl = url.substring(0, url.lastIndexOf("."));
String extension = url.substring(url.lastIndexOf("."));
resizedUrls.add(baseUrl + "/300" + extension);
} else {
resizedUrls.add(url); // 원본 데이터 반환
}
}
return resizedUrls;
}

private static boolean containsValidImageExtension(String url) {
String lowerCaseUrl = url.toLowerCase();
return lowerCaseUrl.contains(".jpeg")
|| lowerCaseUrl.contains(".jpg")
|| lowerCaseUrl.contains(".png")
|| lowerCaseUrl.contains(".webp")
;
}
}
}
13 changes: 7 additions & 6 deletions src/main/java/com/aptner/v3/board/complain/dto/ComplainDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
import lombok.ToString;
import lombok.experimental.SuperBuilder;

import static com.aptner.v3.board.common_post.dto.CommonPostCommentDto.organizeChildComments;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toMiddleSizeImageUrl;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toThumbSizeImageUrl;

@Getter
@ToString(callSuper = true)
Expand Down Expand Up @@ -71,12 +72,12 @@ public ComplainDto.ComplainResponse toResponse() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toThumbSizeImageUrl(dto))
.visible(dto.isVisible())
// post info
.hits(dto.getHits())
.reactionColumns(isSecret ? null : dto.getReactionColumnsDto())
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments())
// complaint
.status(dto.getStatus() == null ? ComplainStatus.RECEIVED : dto.getStatus())
Expand Down Expand Up @@ -112,13 +113,13 @@ public ComplainDto.ComplainResponse toResponseWithComment() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toMiddleSizeImageUrl(dto))
.visible(dto.isVisible())
.comments(organizeChildComments(dto.getCommentDto()))
// .comments(organizeChildComments(dto.getCommentDto()))
// post info
.hits(dto.getHits())
.reactionColumns(isSecret ? null : dto.getReactionColumnsDto())
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments())
// complaint
.status(dto.getStatus() == null ? ComplainStatus.RECEIVED : dto.getStatus())
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/com/aptner/v3/board/free_post/dto/FreePostDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@

import java.time.LocalDateTime;

import static com.aptner.v3.board.common_post.dto.CommonPostCommentDto.organizeChildComments;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toMiddleSizeImageUrl;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toThumbSizeImageUrl;

@Getter
@ToString(callSuper = true)
Expand Down Expand Up @@ -78,12 +79,12 @@ public FreePostResponse toResponse() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toThumbSizeImageUrl(dto))
.visible(dto.isVisible())
// post info
.hits(dto.getHits())
.reactionColumns(isSecret ? null : dto.getReactionColumnsDto())
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments())
// category
.boardGroup(dto.getBoardGroup())
Expand Down Expand Up @@ -121,13 +122,13 @@ public FreePostResponse toResponseWithComment() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toMiddleSizeImageUrl(dto))
.visible(dto.isVisible())
.comments(organizeChildComments(dto.getCommentDto()))
// .comments(organizeChildComments(dto.getCommentDto()))
// post info
.hits(dto.getHits())
.reactionColumns(isSecret ? null : dto.getReactionColumnsDto())
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments())
// category
.boardGroup(dto.getBoardGroup())
Expand Down
13 changes: 7 additions & 6 deletions src/main/java/com/aptner/v3/board/market/dto/MarketDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
import lombok.experimental.SuperBuilder;
import lombok.extern.slf4j.Slf4j;

import static com.aptner.v3.board.common_post.dto.CommonPostCommentDto.organizeChildComments;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toMiddleSizeImageUrl;
import static com.aptner.v3.board.common_post.dto.CommonPostDto.CommonPostResponse.toThumbSizeImageUrl;

@Slf4j
@Getter
Expand Down Expand Up @@ -81,12 +82,12 @@ public MarketResponse toResponse() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(dto.getImageUrls())
.imageUrls(toThumbSizeImageUrl(dto))
.visible(dto.isVisible())
// post info
.hits(dto.getHits()) // 조회수
.reactionColumns(isSecret ? new ReactionColumnsDto(0L,0L) : dto.getReactionColumnsDto()) // 공감
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments()) // 댓글 수
// category
.boardGroup(dto.getBoardGroup())
Expand Down Expand Up @@ -125,13 +126,13 @@ public MarketResponse toResponseWithComment() {
// post
.title(dto.getTitle())
.content(isSecret ? blindContent : dto.getContent())
.imageUrls(isSecret ? null : dto.getImageUrls())
.imageUrls(isSecret ? null : toMiddleSizeImageUrl(dto))
.visible(dto.isVisible())
.comments(organizeChildComments(dto.getCommentDto()))
// .comments(organizeChildComments(dto.getCommentDto()))
// post info
.hits(dto.getHits()) // 조회수
.reactionColumns(isSecret ? null : dto.getReactionColumnsDto()) // 공감
.reactionType(isSecret ? ReactionType.DEFAULT : dto.getReactionType())
.reactionType(isSecret || dto.getReactionType() == null ? ReactionType.DEFAULT : dto.getReactionType())
.countOfComments(dto.getCountOfComments()) // 댓글 수
// category
.boardGroup(dto.getBoardGroup())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Tag(name="공지 사항")
Expand Down Expand Up @@ -67,7 +68,8 @@ public ResponseEntity<?> getPostListByCategoryId(@RequestParam(name = "start") L
) {
List<NoticePost> searched = noticePostService.getNoticePostsByScheduleRange(start, end, getBoardGroup());
// 아파트너사와 동일한 형태 응답값
return ResponseEntity.ok(searched);
List<NoticePostDto.NoticeResponse> response = searched.stream().map(p -> p.toDto().toResponse()).collect(Collectors.toList());
return ResponseEntity.ok(response);
}

public BoardGroup getBoardGroup() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,21 @@ public class NoticePost extends CommonPost {
public NoticePost() {
}

public NoticePost(Member member, Category category, String title, String content, List<String> imageUrls, boolean visible, LocalDateTime postAt) {
public NoticePost(Member member, Category category, String title, String content, List<String> imageUrls, boolean visible, boolean isImport, boolean isDuty, LocalDateTime scheduleStartAt, LocalDateTime scheduleEndAt, LocalDateTime postAt) {
super(member, category, title, content, imageUrls, visible);
this.isImport = isImport;
this.isDuty = isDuty;
this.scheduleStartAt = scheduleStartAt;
this.scheduleEndAt = scheduleEndAt;
this.postAt = postAt;
}

public static NoticePost of(Member member, Category category, String title, String content, List<String> imageUrls, boolean visible, LocalDateTime postAt) {
return new NoticePost(member, category, title, content, imageUrls, visible, postAt);
return new NoticePost(member, category, title, content, imageUrls, visible, false, false, null, null, postAt);
}

public static NoticePost of(Member member, Category category, String title, String content, List<String> imageUrls, boolean visible, boolean isImport, boolean isDuty, LocalDateTime scheduleStartAt, LocalDateTime scheduleEndAt, LocalDateTime postAt) {
return new NoticePost(member, category, title, content, imageUrls, visible, isImport, isDuty, scheduleStartAt, scheduleEndAt, postAt);
}

@Override
Expand Down
Loading

0 comments on commit 9868617

Please sign in to comment.