본문 바로가기

C#/C# FullStack

[Blazor Assembly] 이미지 파일 업로드

흐름
1. 썸머노트 적용된 클라이언트 페이지에서 이미지 업로드
2. JS 스크립트의 썸머노트 콜백에서 클라이언트 페이지의 c#코드 호출함
3. 클라이언트 페이지에서 파일 업로드 서비스 호출함
4. 파일 업로드 서비스가 파일 업로드 api 호출함
5. 서버에서 파일 업로드 서비스 호출

*썸머노트 - 사진, 표, 글씨체 등등 조절 가능한 자바 스크립트 에디터 모듈

클라이언트 페이지

[JSInvokable]
public async Task<string?> UploadImageFile(string base64Image)
{
        try
        {
            await BoardService.UploadBase64Image(new Base64Dto { Base64 = base64Image });        
            return base64Image; 
        } catch (Exception ex)
        {
            var errorMessage = JsonConvert.DeserializeObject<ErrorMessageDto>(ex.Message);
            if (errorMessage != null)
            {
                await JSRuntime.InvokeVoidAsync("notif", "danger", errorMessage.Detail); //토스트 메시지 띄우기
            }
            return "";
        }

    }
  • JSInvokable - 자바 스크립트에서 c# 코드 호출할 수 있게 해줌
  • 굳이 base64 DTO만든 이유 - base64 문자열 길이가 너무 길어서 파라미터로 전달할 수 없다. json 형태로 전달해야한다.

서버

nuget에서 SixLabors.ImageSharp 설치 필요

using SixLabors.ImageSharp;
...
public async Task UploadBase64Image(Base64Dto base64)
{
			if (string.IsNullOrEmpty(base64.Base64))
				throw new ArgumentNullException();

			var imageFile = Convert.FromBase64String(base64.Base64.Split(',')[1]);
//data:image/png; 같은 포멧 정보 제거하고 순수 base64 스트링만 얻기
			// 기본 가로 길이에 맞게 이미지 크기 조정 
			var defaultWidth = 600;  //기본 가로 길이. 설정파일 같은데 저장해두기
			using (var image = Image.Load(imageFile))
			{
				var width = image.Width;
				var height = image.Height;

				if (width > defaultWidth)
				{
					var calculatedWidth = image.Width / defaultWidth;
					width = (int)(width / calculatedWidth);
					height = (int)(height / calculatedWidth);
				}

				image.Mutate(x => x.Resize(width, height, KnownResamplers.Lanczos3));
				var randomFileName = Guid.NewGuid().ToString() + ".jpg";

				await image.SaveAsync("C:/savepath/" + randomFileName, new JpegEncoder());
			}
		}