4달 전 · @SoftyChoco 님의 새로운 답변
게시글 이미지 업로드를 구현하는데 궁금한 점이 있습니다.
velog를 참고하여 Spring + Vue를 이용하여 마크 다운 기반 게시글을 구현하고 있습니다.. 글을 쓰는 도중에 이미지를 올리면 s3에서 url를 반환하여, 이것을 통째로 Post 테이블 Content 필드에 저장하여 순서를 보장하는 식으로 진행하고 있습니다. 로직 흐름은 이렇습니다. 1. 사용자가 이미지를 올린다면, 클라이언트에서 글쓰기 버튼을 눌렀을 때 미리 만들어 놓은 UUID와 이미지를 서버로 보낸다. 2. 서버에서는 s3객체에 임시 저장 여부를 확인하는 isTemp를 태그를 넣어서 서버를 걸쳐서 S3에 쏜다. 3. S3에서 객체를 찾아서 key값과 클라이언트에서 보낸 uuid를 Image 테이블에 저장해서 Post와 간접적으로 연관 관계를 맺는다. 4. 글쓰기를 누른다면 내용과 UUID를 보내서 UUID를 Post의 primary key로 사용하고, UUID 기반으로 Image 테이블에서 key들을 갖고 와서 S3 객체의 isTemp 태그를 false로 바꾼다. 4-1 . 뒤로 가기나 임시 저장을 눌렀을 때는 isTemp를 true로 설정하고 저장한다. 5. 30일이 지날 때마다, Post에 있는 isTemp를 통해 임시 여부를 확인하여 임시 저장된 글을 삭제하고, S3에서는 수명 주기를 설정하여 태그를 기반으로 true인 이미지들을 삭제한다. 객체를 삭제하는 이유는 불필요한 데이터가 공간을 차지하는 것이 별로라고 판단했습니다. UUID는 글을 다 쓰기도 전에 서버로 쏘기 때문에, 어떤 게시글에서 쓰였는지 확인하기 위해서 사용했습니다. 성능이나 용량 면에서 안 좋다고 하지만, 이는 데이터를 넣어 놓고 조회를 하여 성능을 확인하였고 현재 프로젝트 크기를 생각했을 때 접목해도 상관없을 것 같아 넣었습니다. 하지만 이런 식으로 진행하니, 만약 사용자가 중간에 이미지 링크를 삭제한다면? 이라는 시나리오를 생각했을 때 이를 대처할 방도가 떠오르지 않습니다. 다른 분들은 어떤 식으로 처리했는지, 제가 너무 어렵게 생각하고 짜는지 궁금합니다.
개발자
#spring-boot
#s3
#게시글
답변 1
댓글 0
조회 61
6달 전 · 전재욱 님의 새로운 댓글
자바스크립트의 이벤트 처리 질문
리액트로 이미지 inpainting 컴포넌트를 만들고 있습니다. 사용자가 이미지 업로드를 하면 canvas 영역에 그 이미지가 채워지고 그 이미지에 mask 영역을 칠할 수 있는 이미지 에디터 컴포넌트인데요, 궁금한게 생겨 질문드립니다. 첨부한 코드는 컴포넌트의 코드중 이미지 업로드 시 onChange 이벤트의 처리기인 handleImageUpload 함수와, handleImageUpload 함수에서 호출되는 loadImage 함수의 코드입니다. 사용자가 input 요소에 이미지를 업로드하면 onChange 이벤트가 발생해 handleImageUpload 함수가 실행되고 loadImage 함수가 실행됩니다. loadImage 함수가 실행되면 img 객체가 생성되고 img 객체의 src를 지정하죠. 그러면 브라우저는 이미지 로딩을 시작하고 이미지 로딩이 완료되면 onload 콜백함수가 실행됩니다. 저는 이 과정을 자바스크립트의 콜스택, 이벤트 루프, 태스크큐 구조에서 나타내보자면 다음과 같다고 생각했습니다. 1. 초기상태 콜스택 : [ ] 태스크큐 : [ ] 2. 사용자가 파일을 업로드 -> onChange 이벤트 발생 콜스택 : [handleImageUpload] 태스크큐 : [ ] 3. handleImageUpload 내부에서 loadImage 함수 호출 콜스택 : [handleImageUpload, loadImage] 태스크큐 : [ ] 4. loadImage 내부에서 img 객체 생성 및 src 할당 콜스택 : [handleImageUpload, loadImage] 태스크큐 : [ ] Web API : 이미지 로딩 시작 5. loadImage 함수 종료, handleImageUpload 함수 종료 콜스택 : [ ] 태스크큐 : [ ] Web API : 이미지 로딩 진행중 6. 이미지 로딩이 완료되면 Web API가 onload 콜백을 태스크큐에 추가 콜스택 : [ ] 태스크큐 : [onload] Web API : 이미지 로딩 완료 7. 이벤트 루프가 콜스택이 비어있음을 확인하고 태스크큐에서 onload 콜백을 콜스택으로 이동 콜스택 : [onload] 태스크큐 : [ ] 8. onload 콜백 실행 (캔버스에 이미지 그리기 등) 콜 스택 : [onload, drawImage, ...] 태스크큐 : [ ] 일단 이 과정이 맞나요? 만약 이게 맞다면 생기는 궁금증이 있습니다. Web API에서 이미지 로딩이 진행되는동안 loadImage 함수 및 handleImageUpload 함수가 종료되면 loadImage 함수 내에서 생성된 img 객체는 가비지 컬렉터에 의해 지워져야 하지 않나? 그렇게 img 객체가 GC에 의해 사라지면 이미지 로딩이 완료되었을 시점엔 img 객체의 onload 함수도 없어진것이니 onload 함수의 로직은 실행이 되지 않아야 하는 거 아닌가? 하는 생각이 들어 질문드립니다
개발자
#자바스크립트
#react
#frontend
답변 1
댓글 1
조회 254
6달 전 · Supernova 님의 새로운 답변
커리어리 개발툴은 뭘로 만들어졌을까요, 서버 최적화 방법 질의
커리어리 웹뷰는 뭘로 만들어졌나요 ? 우연히 커리어리를 알게 되어서 사이트를 구경하던중 글 남깁니다. 저는 올해 40세이고 취미로 코딩을 배우면서 현재는 메타의 threads 와 비슷한 웹뷰를 만들고 있습니다. 독학으로 배우다보니 깊이가 없어서 한계에 직면해 있는거 같아요. 커리어리에서 스크롤을 내리다보면 딜레이 없이 페이지들이 거의 무한으로 내릴 수 있던데 기술적으로 그게 참 궁금하고요. 게시글을 포스트 했을때도 거의 딜레이 없이 게시물 업데이트가 되더라구요. 저 같은 경우에는 Next JS 로 웹뷰를 구성했고 database 는 vercel neon (무료버전. 서버는 싱가폴위치) Image 는 uploadthing (100GB 유료걸제 10$. 서버는 한국) 게시글 post 시에 단순 텍스만 입력을 하더라도 업로드 되고 화면에 뿌려지는데 2~3초의 딜레이가 발생합니다. database 가 무료 버전에 싱가폴에 있어서 반응이 느린건지 코드 최적화가 문제인지 모르겠습니다. 제가 테스트중인 사이트 주소는 아래와 같습니다. https://newchat-omega-inky.vercel.app/ 게시글 업로드 속도만 높일 수 있다면 정말 좋을 거 같은데 뭔가 벽에 막힌거 같습니다 ㅜㅜ
개발자
#커리어리-개발툴
#서버최적화
답변 1
댓글 0
조회 91
8달 전 · 노원재 님의 답변 업데이트
ReactNative ios build 에러 3일째 해결을 못했습니다.
시뮬레이션을 실행하려고 해도 스크립트 문제, iPhone 버전 범위 문제, 시뮬레이터 문제가 계속 발생합니다. 어떤 도움이라도 감사합니다. ReactNative를 처음 접했습니다. 저희 팀에서 저를 도울 수 있는 사람이 없습니다. #프로젝트 환경 mac M2 ruby -v ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin23] node -v v20.10.0 pod --version 1.15.2 package.json { "name": "labts", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "lint": "eslint .", "start": "react-native start", "test": "jest" }, "dependencies": { "@react-native-community/async-storage": "^1.12.1", "@react-native-community/cli": "13.6.9", "@react-navigation/bottom-tabs": "^6.6.0", "@react-navigation/native": "^6.1.17", "@react-navigation/native-stack": "^6.10.0", "@tanstack/react-query": "^5.51.5", "@types/react-native-vector-icons": "^6.4.18", "axios": "^1.7.2", "date-fns": "^3.6.0", "immer": "^10.1.1", "react": "18.2.0", "react-native": "0.74.3", "react-native-calendars": "^1.1305.0", "react-native-date-picker": "^5.0.4", "react-native-dotenv": "^3.4.11", "react-native-get-random-values": "^1.11.0", "react-native-image-crop-picker": "^0.41.2", "react-native-image-zoom-viewer": "^3.0.1", "react-native-paper": "^5.12.3", "react-native-permissions": "^4.1.5", "react-native-safe-area-context": "^4.10.8", "react-native-screens": "^3.32.0", "react-native-splash-screen": "^3.3.0", "react-native-tab-view": "^3.5.2", "react-native-vector-icons": "^10.1.0", "react-native-vision-camera": "^4.5.1", "uuid": "^10.0.0", "yarn": "^1.22.22" }, "devDependencies": { "@babel/core": "^7.20.0", "@babel/preset-env": "^7.20.0", "@babel/runtime": "^7.20.0", "@react-native/babel-preset": "0.74.85", "@react-native/eslint-config": "0.74.85", "@react-native/metro-config": "0.74.85", "@react-native/typescript-config": "0.74.85", "@types/react": "^18.2.6", "@types/react-native-dotenv": "^0.2.2", "@types/react-test-renderer": "^18.0.0", "babel-jest": "^29.6.3", "babel-plugin-module-resolver": "^5.0.2", "eslint": "^8.19.0", "jest": "^29.6.3", "prettier": "2.8.8", "react-test-renderer": "18.2.0", "typescript": "5.0.4" }, "engines": { "node": ">=18" } } PodFile require Pod::Executable.execute_command('node', ['-p', 'require.resolve( "react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]}, )', __dir__]).strip platform :ios, '12.0' use_frameworks! #use_modular_headers! prepare_react_native_project! linkage = ENV['USE_FRAMEWORKS'] if linkage != nil Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green use_frameworks! :linkage => linkage.to_sym end target 'nexlabts' do config = use_native_modules! use_react_native!( :path => config[:reactNativePath], # An absolute path to your application root. :app_path => "#{Pod::Config.instance.installation_root}/.." ) target 'nexlabtsTests' do inherit! :complete # Pods for testing end post_install do |installer| # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 react_native_post_install( installer, config[:reactNativePath], :mac_catalyst_enabled => false, # :ccache_enabled => true ) end end 제가 아래 에러 3가지에 대해 제가 해본 방법들입니다. 1. node 재설치 node_module 폴더 삭제, package-rock.json 삭제 후 재설치 npm install --legacy-peer-deps yarn install 2. Xcode가 node 읽을 수 있도록 설정 sudo ln -s "$(which node)" /usr/local/bin/node 3. Podfile 내 platform 설정 수정 platform :ios, '12.0' or platform :ios, '14.0' 4. Pods 재설치 rm -rf ~/Library/Developer/Xcode/DerivedData or rm -rf ~/Library/Developer/Xcode/DerivedData/* rm -rf Pods rm Podfile.lock pod install --repo-update Xcode \> Product \> Clean Build Folder. cd ./ios pod cache clean -all pod install --repo-update cd ../ npx react-native run-ios --no-packager --simulator="iPhone 15" or npx react-native run-ios --simulator="iPhone 15" or yarn start > i(run ios) Err 1. cocoaPods 설치할 때 [!] CocoaPods could not find compatible versions for pod "React-RuntimeHermes": In Podfile: React-RuntimeHermes (from ../node_modules/react-native/ReactCommon/react/runtime) Specs satisfying the React-RuntimeHermes (from ../node_modules/react-native/ReactCommon/react/runtime) dependency were found, but they required a higher minimum deployment target. Err2. iOS 실행할때 run-ios --no-packager --simulator="iPhone 15" Build description signature: fc1341421f84b87c5245d346c2c17b66 Build description path: /Users/nowonjae/Library/Developer/Xcode/DerivedData/nexlabts-argvodqcybjfcybstpulfpghnzvm/Build/Intermediates.noindex/XCBuildData/fc1341421f84b87c5245d346c2c17b66.xcbuilddata /Users/nowonjae/Desktop/project/NeXLabRN/ios/nexlabts.xcodeproj:1:1: error: Unable to open base configuration reference file '/Users/nowonjae/Desktop/project/NeXLabRN/ios/Pods/Target Support Files/Pods-nexlabts/Pods-nexlabts.release.xcconfig'. (in target 'nexlabts' from project 'nexlabts') warning: Unable to read contents of XCFileList '/Target Support Files/Pods-nexlabts/Pods-nexlabts-resources-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') warning: Unable to read contents of XCFileList '/Target Support Files/Pods-nexlabts/Pods-nexlabts-frameworks-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-frameworks-Release-input-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-frameworks-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') warning: Run script build phase 'Bundle React Native code and images' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'nexlabts' from project 'nexlabts') warning: Run script build phase '[CP] Embed Pods Frameworks' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-resources-Release-input-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') error: Unable to load contents of file list: '/Target Support Files/Pods-nexlabts/Pods-nexlabts-resources-Release-output-files.xcfilelist' (in target 'nexlabts' from project 'nexlabts') warning: Run script build phase '[CP] Copy Pods Resources' will be run during every build because it does not specify any outputs. To address this warning, either add output dependencies to the script phase, or configure it to run in every build by unchecking "Based on dependency analysis" in the script phase. (in target 'nexlabts' from project 'nexlabts') --- xcodebuild: WARNING: Using the first of multiple matching destinations: { platform:iOS Simulator, id:B5AA2E84-4F83-4749-A986-A1FCE5E398A3, OS:17.5, name:iPhone 15 } { platform:iOS Simulator, id:B5AA2E84-4F83-4749-A986-A1FCE5E398A3, OS:17.5, name:iPhone 15 } ** BUILD FAILED ** ] Err3. Xcode 로 Build 할때 (Any iOS Simulator Device (arm64, x86_64)) Command PhaseScriptExecution failed with a nonzero exit code
개발자
#reactnative
#xcode
#reactnative-run-ios
답변 1
댓글 0
조회 531
일 년 전 · 백승훈 님의 새로운 답변
react-query로 이미지를 가져올 때, 이미지가 깜빡거리는 문제를 해결하고 싶어요.
React 프로젝트에서 차량 데이터 목록(차량 모델 사진, 차량명, ....등)을 보여주는 웹 프로젝트를 진행하고 있습니다. 차량 데이터 목록 화면에서 react-query를 통해 가져온 데이터는 (예시 데이터) const data = [{id: number, car_name: string, model_name, car_model_image: number...}, {.....} ] 이런식으로 가져와서 map을 통해 CarCard 컴포넌트에 데이터를 props로 보내어 현재 출력하고 있습니다. 여기서 이미지 같은 경우는 백엔드에서 차량 모델 이미지를 가져오는 api를 따로 만들어놓아서, props로 전달받은 car_model_image 즉, 차량 모델 이미지의 id를 통해서 차량 모델 이미지 api에 데이터를 요청해서 이미지를 출력하고 있습니다. 이때. 페이지를 전환하거나, 한 페이지에서 아무동작을 하지 않아도 게속 이미지가 깜빡거리면서 재렌더링이 되고, 계속 무한정으로 이미지를 호출하는 문제가 발생하였습니다. map을 통해 CarCard를 호출하고 CarCard 안에서 이미지를 호출함에 따라서 계속 이미지가 깜빡깜빡 거리는 것 같은데, 컴포넌트 안에서 이미지를 호출할 때 어떻게 하면 무한정으로 이미지를 불러오지 않도록 하고 깜빡거림을 없앨 수 있을까요 ?...어떻게 해결해야 할지 감이 안 잡혀요.... //차량 목록 페이지 한 부분 ... const { data } = useGetCarList(); //useQuery를 통해 서버에서 데이터 전달받음 // const data = [{id: number, car_name: string, model_name, car_model_image: number...}, {.....} ] 이런식 .... return ( <div> data.map((data: CarData) => { return ( <Carcard ascCarData={data} key={Math.random()} handleClick={() => handleClick(data)} isActive={true} /> ); }) </div> ) //Carcard 컴포넌트 const { data: carImage } = useGetCarModeImage(ascCarData.car_model_image); // 이미지 데이터 가져오기
개발자
#react
#vite
#react-query
#typescript
#react-query-v3
답변 4
댓글 0
조회 327
일 년 전 · 김하늘 님의 답변 업데이트
개발 공부를 어떻게 하는게 좋을까요? (feat. 프로젝트)
얼마 전 Next.js로 개인 프로젝트를 진행했습니다. 그런데 프로젝트를 진행해보며 제가 어떤 방식으로 개발 공부 뱡향성을 잡아야하는지 혼란스러워 질문드립니다 ,, 🙏 처음 Next.js 쓸 때는 복붙 ,, 같은 기능도 복붙해서 파일 여러 개 만들기를 하고, 서버 컴포넌트와 클라이언트 컴포넌트에 대해 잘 알지 못한채로 프로젝트를 했었습니다. (+ 상태관리나 ,, 이런 것도 아예 모르고 개발했었습니다 ,,) 이번에 제대로 공부해서 기능을 구현해보고 싶어 다시 시작해서 완성했습니다. 그런데 제가 작성한 코드를 다 이해하며 작성했지만, **제가 작성한 코드가 좋은 코드인지? 에 대한 의문이 생겼습니다.** 그래서 팀 프로젝트도 참여해보며 같은 프론트 팀원 분의 코드를 확인해보며 좋아보이는 부분은 참고도 했지만, 이 방법도 한계가 있었습니다. 더 잘해보고 싶어 빨리 보여져야하는 이미지는 이미지를 미리 로드한다거나, next/image로 이미지 최적화를 하고 최대한 코드 중복을 줄이고자 공통 컴포넌트들을 만들기 위해 노력하긴 했었습니다. (나중에 스토리북 이라는 라이브러리를 알게되어 이걸 사용해보지 못한게 아쉽긴 했습니다.) 그래도 많이 부족한거 같아 어떻게 더 나은 개발을 해야할지 잘 모르겠습니다 ,, 첫 프로젝트에서는 부트스트랩 외에는 사용해보지 않아 이번에 제대로 다양한 기술을 써보고자 시도도 해보았습니다. (> 서버 상태 관리를 위해 tansack query도 사용해보고 클라이언트 상태 관리를 위해 recoil을 사용하고, 스타일링에는 css in js가 궁금해 styled components, 직접 어느정도 깔끔한 디자인을 하고싶어 피그마 툴을 이용해보았습니다. 소셜 로그인도 넣어보고 몽고 db 사용하며 데이터베이스도 연결해보았는데 ,, 막상 완성하고 나니 제가 많이 부족하다는 생각이 들었습니다.) 🤔 제가 작성한 코드가 좋은 코드인지 ,, 더 나은 성능을 위해 어떤 개발을 하면 좋은지와 같은 부분은 제가 어떻게 학습하는게 가장 좋은 방법일까요? 또한 어떤 것을 더 배워서 적용해보는게 좋을까요? ,, (제가 생각했을 때 프로젝트를 완성은 했지만, 제 프로젝트의 매력적인 점이 없는거 같아 너무 아쉬운거 같습니다.)
개발자
#프로젝트
#next.js
#좋은코드
#공부방법
답변 1
댓글 1
추천해요 2
조회 211
일 년 전 · 양승완 님의 새로운 댓글
sns기능을 구현중에 있습니다.
swift 로 sns 기능을 구현 중에 있습니다. 메모리 관리를 위해 테이블 뷰로 피드 창을 구현하였는데 Pagination을 위하여 테이블뷰 셀 안에 스크롤뷰를 구현에 그 안에 frame에 맞춰 Imageview를 넣어주었습니다. 이 상황에서 무한 스크롤 , 새로고침 기능 시 셀 재사용으로 인하여 이전 셀의 이미지가 살짝 보였다가 현재의 이밎로 보이거나 override된 셀의 prepare reuseable 함수에서의 초기화를 함에도 깜빡이는 현상이 지속됩니다. 혹시 좋은 의견 있으신가 여쭤봅니다!
개발자
#rxswift
#swift
#xcode
#ios
답변 1
댓글 1
조회 134
일 년 전 · 익명 님의 질문
Streamli app Azure에 배포시.
Python Streamlit으로 앱을 하나 작성 했고 Docker image로 빌드해서 azure container repository에 푸쉬 했습니다. 그리고 이미지를 기반으로 app service를 띄웠는데요. 로컬에서는 아무 문제 없이 작동이 되는데 리모트로 올라가니 streamlit cookie manager 및 feedback component를 로딩하질 못 합니다. (사실 쿠키 매니저는 설치한 적이 없어서 왜 문제가 되는지 더더욱 잘 모르겠네요) 에러 문구에는 네트워크 레이턴시나 프록시 이슈로 컴퍼넌트를 로딩 못 하는 걸수 있다 라고 하는데 혹시 관련해서 비슷한 이슈 해결하신분 계실까요?
개발자
#streamlit
#azure
#docker
#appservice
답변 0
댓글 0
조회 82
일 년 전 · 그린티라떼 님의 새로운 답변
react에서 복잡한 상태를 관리할때.. 한번에 관리? 분리해서 관리? (jotai, recoil, useState)
안녕하세요 react를 이용해서 복잡한 작성 페이지를 만들고있습니다. 아래의 타입은 예시입니다. type payload = { name: string; message: string; type: string; url: { pc: string; mobile: string; }; contents: { images: { url: string; name: string; }[]; buttons: { name: string; url: string; }[]; }; conditions: { ... }, .... }; 위처럼 복잡한 데이터를 서버로 보내줘야해서 데이터를 관리해야하는데 현재는 페이지내에 구조가 복잡하고 컴포넌트도 매우많아 props drilling이 너무 심해질거같아서 recoil, jotai와 같은 상태관리 라이브러리를 이용해서 작업을 진행하고있습니다. 이러한 상황에서 관리하는 데이터를 한객체에 모아서 관리하는게 좋은지 아니면 const nameAtom = atom(''); const messageAtom = atom(''); const typeAtom = atom(''); const urlAtom = atom({ pc: '', mobile: ''}); .... 처럼 일일히 쪼개서 관리하는게 맞는 방향인지 모르겠어서 질문드립니다 ! (사수가없어서 물어볼곳이없어요...) 현재는 아래와같이 쪼개서 작업한뒤 submit시에 합쳐주는 방식으로 구현해놓았는데 atom 갯수가 20개 정도 되버리니까 너무 복잡해보여서 이게맞나... 싶어서 질문드리게되었습니다.
개발자
#react
#frontend
답변 2
댓글 0
보충이 필요해요 1
조회 247
일 년 전 · 이지헌 님의 새로운 댓글
Next.js 이미지 최적화 방식에 대해 질문이 있습니다.
안녕하세요! Next.js 14를 사용해 프로젝트를 진행하던 중 이미지 최적화에 관해 궁금한 점이 생겨서 이 곳에 질문을 남깁니다. 프로젝트를 하며 약 500개의 이미지를 랜덤으로 추천해서 렌더링하는 기능을 구현했습니다. 현재 작업 방식은 프로젝트에서 페이지에서 이미지를 업로드 하는 기능은 필요가 없기에 MongoDB에 이미지 'URL'을 모두 저장하고 클라이언트에서 서버로 요청하면 서버에서 DB에 있는 URL을 리턴해주면 그걸 <img> 태그를 이용해서 화면에 띄우는 방식으로 구현했습니다. 하지만, 이렇게 구현하니 이미지 렌더링 속도가 조금 늦는 현상이 발생해 이를 최적화하고 싶습니다. 제가 생각했던 방법들은 다음과 같은데 어떤 방법이 좋은지, 혹은 더 나은 방법이 있는지 아시는 분이 있으면 추천해주시면 감사하겠습니다. 1. 이미지를 모두 다운받아 public 폴더에 넣고 Next/Image를 사용한다. -> 이 방법을 하려니 사진이 500개가 되고 사진마다 png,jpg 형식도 달라서 적용하는 것도 어려울 것 같고 무엇보다도 프로젝트 파일 사이즈가 커지는게 문제가 될 것 같다는 생각을 했습니다. 만약 사진이 500개가 아니라 1000개 2000개가 된다면 더더욱 그럴 것 같아서요. 이 부분에서 추가로 생각해본 방식이 파일 형식을 모두 avif로 바꾸는건데 그런 접근도 괜찮은건가요? 2. 서버에서 URL 넘어온 그대로 Next/image를 사용한다. -> 모든 파일의 url 형식이 달라서 일일이 next.config.ts에서 설정해주는 게 쉽지않을 것 같다고 생각했습니다. 그래서 모든 파일을 AWS S3에 올려놓으면 URL 주소가 같을테니 그렇게 하는 게 맞는지 궁금했습니다. 아직 제 지식이 짧아서 생각해본 방식은 위와 같은데, 추가로 좀 더 좋은 방식이나 현업에서 사용하는 방식이 있다면 알려주시면 감사하겠습니다. 긴 글 읽어주셔서 감사합니다!!!
개발자
#next.js
#리액트
#이미지최적화
#넥스트
답변 1
댓글 1
추천해요 1
조회 211
일 년 전 · 김현우 님의 댓글 업데이트
vercel로 배포를 했는데 이미지가 화면에 업로드가 안되는데 뭐가 원인일까요??
vscode에서 리액트 프로젝트를 만들었고 vercel로 사이트를 배포했습니다. 배포된 사이트를 들어가면 전체적으로 잘 작동을 하는데 이미지 하나가 화면에 안뜨네요... 개발자 도구로 확인을 해보면 이미지를 불러오고 있기는 한데, 화면에는 안뜨는 이유가 뭘까요? 이미지는 화면 전체를 감싸는 컨테이너 컴포넌트에 스타일 컴포넌트를 적용하고 있는데 background에서 url을 불러오는 방식을 사용하고 있습니다. ex) const Container = styled.div` background: url('/images/Image.svg') ` 위와 같은 형식으로 작성을 했습니다. 원인이 뭘까요??
개발자
#프론드엔드
#react
답변 1
댓글 5
추천해요 1
조회 656
일 년 전 · 익명 님의 질문
멀티모달 분야 어디서부터 공부하면 좋을까요?
안녕하세요. 컴퓨터 비전 분야 쪽으로 공부하고 있는 학부생입니다. LLM의 발전으로 향후 멀티모달 분야 (text2image, text2video) 등이 핫해질 것 같아 대학원에서 멀티모달 관련 연구를 해보고 싶습니다. 이를 위해 멀티모달 공부를 미리 해보고자 하는데요. 현재 CLIP이라는 논문까지는 읽어본 상황입니다. 더 나아가 어떤 논문을 읽어보는 것이 좋을지, 멀티모달 흐름을 잘 알 수 있게 하는 참고자료나, 연구주제가 있을까요? 읽어주셔서 감사합니다.
개발자
#멀티모달
#인공지능
답변 0
댓글 0
조회 108
일 년 전 · 백승훈 님의 새로운 댓글
Nextjs를 정적 웹 호스팅(dothome)으로 배포하게 될 때 문제점
안녕하세요. 이번에 맡게된 프로젝트에서 SEO가 중요하다고 판단되어 Nextjs를 사용하여 개발하였습니다. 그런데 저희 팀이 사용하고 있는 웹 호스팅 서버가 dothome입니다. dothome은 정적 웹 사이트 호스팅 서버라고 알고 있는데, 이 서버로 호스팅하게 되면 몇 가지 문제점이 있다고 판단되어 질문을 남기게 되었습니다. 1. dothome에 배포하기 위해 정적 빌드를 하게 되면, 서버 사이드 렌더링(SSR) 기능을 사용할 수 없게 되는데, 이는 NextJS를 사용해서 얻을 수 있는 SEO 측면의 이점을 얻을 수 없게되는 건가요? 그렇게 된다면 SEO를 개선하는 방법이 있을까요? 2. Nextjs에서 제공하는<Image> 태그가 서버 측에서 이미지 최적화기능을 제공하는 것으로 알고 있는데, 정적빌드를 사용하게 되면 일반적인 img 태그와 다를 바가 없어지는 걸까요? 3. 마지막으로 Nextjs를 사용하기 위해서 웹 호스팅을 변경하는 것이 좋을지, 변경해야한다면 어떤 것을 추천하지는 시 여쭤봅니다.
개발자
#next.js
#dothome
#ssr
#seo
답변 3
댓글 3
추천해요 4
조회 1,132
일 년 전 · inni 님의 새로운 댓글
Docker Hub Image Push 후에 EC2에서 자동으로 Pull -> service start하기
현재 GithubAction으로 Spring Boot jar 파일을, 도커 빌드, 도커 푸시까지 완료해서 도커 허브에 private repo에 올려놓는데 까지는 성공했습니다. 여기서 두번째 단계로, ssh action을 사용하지 않고 private subnet에 위치한 EC2 instance에서 푸시된 도커 이미지를 가져와서 compose up을 하고 싶습니다. 이걸 수행할 수 있는 팁이나 방법이 있을까요? self-hosted라는게 보이는데 잘 모르겠더라구요.. 제가 찾지 못하는 팁이나 자료들 부탁드립니다! 감사합니다!
개발자
#docker
#ci/cd
#spring-boot
#githubaction
답변 1
댓글 1
보충이 필요해요 1
조회 123
일 년 전 · 류기웅 님의 질문 업데이트
소프트웨어관련학과 전공 2학년 질문드립니다. 미리 조언 감사드립니다.
안녕하십니까 저는 현재 소프트웨어관련학과에 재학중이며 2학년을 마쳤습니다. 일단 저는 대학교에서 처음으로 프로그래밍에 대해서 공부하게 되었습니다. 제가 1,2학년때 배운 것들로는 프로그래밍언어(파이썬, C언어, java) 문법, 파이썬 라이브러리(Pandas, plotlib, numpy)활용, 웹클롤링과 전처리를 통한 빅데이터 분석 팀프로젝트, 이산수학, ai수학(선형대수/최적화) , java를 이용한 안드로이드 모바일 프로그래밍 (위젯, 인텐트 등을 학습), 비주얼테크놀로지의 기반이 되는 영상처리, 컴퓨터비전의 기초 내용( image processing / feature matching / image transform, homography), 소프트웨어공학 입문( 오픈소스소프트웨어, 리눅스 학습) 정도 하였습니다. 대외활동이나 별다른 프로젝트, 블로그, 백준문제풀이등은 하지 않았습니다. 그리고 자료구조와 웹기초(html,css,javascript )관련해서는 2학년때 배우지만 수강신청을 하지 못하여 배우지 못하였으며, 알고리즘은 배우지 않는 것으로 보입니다. 제가 5월 말에 군입영을 준비하고 있는 입장에서 시간이 너무 많이 남았으며 5월까지 전공이나 진로관련하여 아무것도 하지 않고 보내기에는 시간이 너무 아깝다는 생각이 들어서, 뭐라도 해야지 하는 심정으로 현재 자료구조와 웹기초에 대해서 공부를 하고자 하는데요, 자료구조, 알고리즘 공부는 do it자료구조,알고리즘 자바나 다른 책을 이용하거나, 웹기초는 패스트캠퍼스의 '프론트엔드웹 개발의 모든것 초격차 패키지' 강의, java 백엔드는 '시그니처 백엔드 Path 초격차 패키지 Online.'강의를 수강하고자 합니다(사실 강의를 먼저 듣는게 맞는 지는 모르겠는데 이벤트에 혹해서 일단 결제는 했습니다. doit이나 혼공시리즈등의 책으로 먼저 공부한후 강의를 수강하는게 맞을 까요?) 아니면 현재까지 배운것들을 복습하면서 관심이 생기는 부분을 찾는게 맞을까요? 나중에 개발자로서 취업을 하거나 포트폴리오를 작성할때 조금이나마 도움을 받을 수 있는 활동이나 이외에도 개발자가 되기 위한 공부방법, 이 시간을 어떻게 보내면 좋을지 등 여러 의견 남겨주시면 감사하겠습니다. 다른 분들은 혹시 이렇게 남는 시간을 어떻게 보냈는지 궁금하고 남는 시간을 어떻게 하면 조금 더 의미있게 보낼까 고민하다가 혼자 고민하는 것은 너무 답답하다 싶어서 이렇게 질문드립니다....글이 깔끔하지 않은점 죄송합니다...
개발자
#진로
답변 1
댓글 2
추천해요 2
조회 276
9달 전 · 아기 개발자 님의 새로운 답변
Yolov8 모델 저장
안녕하세요 Vscode에서 train폴더에서 model = YOLO("yolov8m.pt") # GPU설정 model = model.to(device) model.train(data='data.yaml', epochs=5) torch.save(model.state_dict(), 'yolov8m_trained.pt') 다음과 같이 모델을 학습 시킨후 Predict폴더에서 # 모델 경로와 이미지 경로를 설정합니다. MODEL_PATH = 'yolov8m_trained.pt' # 모델 가중치 파일의 경로를 설정하세요. IMAGE_PATH = 'image.jpg' # 예측을 원하는 이미지 파일의 경로를 설정하세요. # YOLO 모델을 불러옵니다. model = YOLO("yolov8m.pt") model.load_state_dict(torch.load(MODEL_PATH)) model.eval() 이런식으로 모델을 예측하는 용도로만 사용하고 싶은데 자꾸 모델의 구조가 다르다고 오류가 나는데 어떻게 해야할까요? ㅠㅠ
개발자
#python
#yolo
답변 1
댓글 0
추천해요 1
조회 633
일 년 전 · 민경배 님의 답변 업데이트
리액트 내비게이션 초기 데이터값 설정
import React, { useEffect, useState } from "react"; import { Link, useLocation } from "react-router-dom"; import { TbArrowBigUpFilled } from "react-icons/tb"; import useScroll from "../utils/useScroll"; import useProductsQuery from "../useProductsQuery"; const Nav = () => { const { isNavFixed } = useScroll(); const [activeButton, setActiveButton] = useState(0); const handleButtonClick = (index) => { setActiveButton(index); }; const categoryNames = { materials: "소재별 품목", purposes: "용도별 품목", }; const [isScrollMenuVisible, setScrollMenuVisible] = useState(false); const handleMouseEnter = () => { setScrollMenuVisible(true); }; const handleMouseLeave = () => { // console.log("마우스 이탈"); setScrollMenuVisible(false); }; const location = useLocation(); const isloginorsignup = location.pathname === "/login" || location.pathname === "/signup"; const { isLoading, isError, errorMessage, materials, purposes } = useProductsQuery(); const [hoveredOnedepth, setHoveredOnedepth] = useState(null); const [onedepthChildren, setOnedepthChildren] = useState([]); const [hoveredDivision, setHoveredDivision] = useState(null); const [twodepthDivision, setTwodepthDivision] = useState([]); const handleOnedepthMouseEnter = (item) => { setHoveredOnedepth(item); // console.log(setHoveredOnedepth) setOnedepthChildren(item.children); }; const handletwodepthMouseEnter = (child) => { setHoveredDivision(child); // console.log(setTwodepthDivision); setTwodepthDivision(child.divisions); // console.log(child.divisions); }; if (isLoading) return <>로딩 중...</>; if (isError) return <>{errorMessage}</>; return ( <> {!isloginorsignup ? ( <> {/* 대메뉴 */} <nav id="nav" className={`nav ${isNavFixed ? "fixed" : ""}`}> <div className="nav_wrap"> <div className="twobutton_wrap"> {["materials", "purposes"].map((category, index) => ( <Link type="button" className={`twobutton ${ activeButton === index ? "active" : "" }`} key={index} onClick={() => handleButtonClick(index)} to={`/${category}`} > {categoryNames[category]} </Link> ))} </div> {/* 내비게이션 1depth */} <div className="scrollnav"> <ul className="materialnav" style={{ display: activeButton === 0 ? "flex" : "none", }} > {materials.map((material) => ( <li key={material.id} className="materialnav_li" onMouseEnter={() => { handleOnedepthMouseEnter(material); handleMouseEnter(); }} onMouseLeave={handleMouseLeave} > <Link to="/">{material.name}</Link> </li> ))} </ul> <ul className="usagenav" style={{ display: activeButton === 1 ? "flex" : "none", }} > {purposes.map((purpose) => ( <li key={purpose.id} className="usagenav_li" onMouseEnter={() => { handleOnedepthMouseEnter(purpose); handleMouseEnter(); }} onMouseLeave={handleMouseLeave} > <Link to="/">{purpose.name}</Link> </li> ))} </ul> </div> <div className="call_wrap"> <div className="call"> <div className="call_title">견적 상담 · 문의 대표전화</div> <div className="top_button"> <TbArrowBigUpFilled className="top_icon" /> <p>TOP</p> </div> </div> </div> </div> </nav> {/* 2&3depth 호버 메뉴 */} <div className={`scrollmenu ${isScrollMenuVisible ? "show" : ""} ${ isNavFixed ? "fixed" : "" }`} style={{ visibility: isScrollMenuVisible ? "visible" : "hidden" }} onMouseEnter={handleMouseEnter} onMouseLeave={handleMouseLeave} > {activeButton === 0 && ( <div className="scrollmenu_top"> <ul className="depth2_wrap"> {onedepthChildren.map((child) => ( <li key={child.id} className="depth2_menu" onMouseEnter={() => { handletwodepthMouseEnter(child); }} > <div className="depth2_menu_img_wrap"> <div className="depth2_menu_img"> <img src={child.images[0]._links.href} alt={child.name} /> </div> </div> <p>{child.name}</p> </li> ))} </ul> </div> )} <div className="scrollmenu_middle"> <div className="depth3_wrap"> {twodepthDivision.map((division) => ( <Link key={division.id} to="/" className="depth3_menu"> <span className="depth3_menu_img"> {/* images 속성이 없거나 비어 있어도 오류를 방지 */} {division.images && division.images.length > 0 && ( <img src={division.images[0]._links.href} alt={division.division_name} /> )} </span> <p>{division.division_name}</p> </Link> ))} </div> </div> <div className="scrollmenu_bottom"></div> </div> </> ) : null} </> ); }; export default Nav; 현재는 depth2_menu 호버해야만 depth3_menu가 보이는데 초기에 scrollmenu가 보일때부터 depth2_menu가 (onedepthChildren.map의 첫번째 순서의 데이터가) 호버되어있어 그에 매칭되는 division의 내용들이 depth3_menu에 보이게 할수있는 방법 있을까요 ?
개발자
#react
답변 1
댓글 0
조회 116
2년 전 · 이유진 님의 답변 업데이트
open ai API : image to text
open ai 에 달리처럼 텍스트넣으면 이미지 생성하는 모델이 있는데 open ai 에 반대 경우(이미지를 넣으면 텍스트로)의 모델이나 api 있나요?
개발자
#openai
#imagetotext
#ai
답변 2
댓글 0
조회 313
2년 전 · 삭제된 사용자 님의 새로운 답변
자바 또는 스프링에서 지원하는 html to XML, PDF, Image 컨버팅 라이브러리가 있을까요.
현재 진행하고 있는 상업용 프로젝트가 있는데, html로 받은 인풋을 각각 XML, PDF, 이미지 파일로 컨버팅해야합니다.. 관련해서 찾아보니 aspose사에서 제공하는 라이브러리가 있는데, 라이센스 비용도 있고, 워터마크가 박혀 나오더라구요. 가능하면 자체 개발을 하고 싶은데, html에서 xml 파싱하는 건 어느 정도 어떻게 해야겠다.라는 느낌이 오는데 다른 두 형식은 감도 안 오더라구요. 혹 제가 모르는 스프링 지원 라이브러리가 있는 지, 자체 개발시 방향성이나 드는 시간 정도 조언해주시면 정말 감사하겠습니다 ㅠㅠ
개발자
#java
#spring
#html
#변환
#convert
답변 1
댓글 0
조회 101
2년 전 · 익명 님의 질문
자바 이미지크기 조절
자바 2기가 넘는 tiff이미지 파일을 크기 조절 하려고하는데 ImageIo.read(이미지파일) 하는 부분에서 이미지 파일이 너무 큰 탓에 가로세로 합이 integer.maxvalue를 훨씬 초과해서 익셉션이 나네요.. 이미지파일을 건드려면 read가 선행되어야 뭘 할텐데 어떻게 방법이 없을까요?
개발자
#스프링
#자바
답변 0
댓글 0
조회 61
2년 전 · 이상선 님의 새로운 답변
Lighthouse를 이용한 성능 최적화 - 텍스트 압축 사용
안녕하세요. 개발한 웹 페이지를 lighthouse를 통해 성능 최적화에서 난관을 겪고 1년차 React 개발자입니다. lighthouse에서 추천 항목에 "텍스트 압축 사용"을 적용해보려 시도 중입니다. .htaccess 파일에 다음과 같은 코드를 넣어서 텍스트 압축을 실행하였습니다. <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE image/svg+xml AddOutputFilterByType DEFLATE text/plain AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/xml AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/x-font-ttf AddOutputFilterByType DEFLATE application/vnd.ms-fontobject AddOutputFilterByType DEFLATE font/opentype font/ttf font/eot font/otf </IfModule> 결과적으로 네트워크 탭에서 Content-Encoding: gzip 으로 표시되는 것을 보니까, 텍스트 압축이 되는 것처럼 보입니다. 그런데 lighthouse에서는 성능 점수가 더 올라가지 않고 있습니다. 혹시 "텍스트 압축" 부분에서 최적화 하는 다른 방법이 있을까요? 아니면 제가 놓치고 있는 부분이 있는 걸까요?
개발자
#react
#lighthouse
#front-end
답변 1
댓글 0
조회 330
2년 전 · 이상선 님의 새로운 답변
Async await fetch 오류
const Content: React.FC = () => { const [htmlContent, setHtmlContent] = useState<string>(''); const data = { "filePath": ""https://cdn-image-dev.test.io/dev/contents/terms/2023/10/11/",", "fileName": "test.html" } const url = `${data.filePath}${data.fileName}`; // HTML 파일 가져오기 const fetchHtmlFile = async () => { try { const res = await fetch(url); console.log('res', res); if (res.ok) { const html = await res.text(); setHtmlContent(html); } else { console.error('Failed to fetch HTML file'); } } catch (error) { console.error('Error fetching HTML file:', error); } }; fetchHtmlFile(); return( <div dangerouslySetInnerHTML={{ __html: htmlContent }} /> ) } fetchHtmlFile 호출 시켜 res에서 얻은 html소스를 가져와 htmlContent에 넣어야하는데 에러나네요,, **에러메세지 Content.tsx:30 Error fetching HTML file: TypeError: Failed to fetch Cors 오류 참고 -- api url : https://api-dev.test.io/api/test/v1/~~ 도와주세요!
개발자
#react
#html
#async
#fetch
답변 1
댓글 0
조회 97
2년 전 · 손우진 님의 새로운 답변
프론트엔드 기술 고민
안녕하세요! 백엔드분들과의 프로젝트를 앞두고 있는데, 고민이 한가지 있습니다. 프론트엔드 팀원은 저 포함해서 3명인 상황입니다. 기술스택을 정할떄, 리액트를 쓸지 Next를 쓸지 고민을 하고 있고, Next를 써 본적이 있는 팀원은 1명인 상황입니다. Next를 썼을 떄 장점은 - 랜더링 전략을 다르게 가져갈 수 있다 - SEO를 쉽게 최적화할 수 있다 - Route Handler를 통해 요청을 숨길 수 있다. - 여러자체 컴포넌트 (Image,Link등...)을 쓸 수 있다. 이 정도가 있을 것 같은데 현업에서 react->Next로 전환할떄 어떤 시점에 전환하셨는지, 전환했을때 어떻게 팀원들끼리 협의를 하셨는지 궁금합니다..!
개발자
#react
#next.js
답변 3
댓글 0
추천해요 1
조회 195
2년 전 · 정하승 님의 질문 업데이트
api의 첫번째 호출 이후부터 antd Button 렌더링 안되는 이슈가 있습니다.
```jsx import { Popover, Modal, Button, Image, Result } from "antd"; const [prevImg, setPrevImg] = useState(["any"]); const [loading, setLoading] = useState(false); const [removeImgFiles, setRemoveImgFiles] = useState([]); const combinePrevImages = (prevImages, newImages) => { const combinedImages = [...prevImages, ...newImages]; return combinedImages; }; useEffect(() => { const postSeg = async () => { try { const res = await axios.post( "apiurl", { filepath: filePath, clips: sortableList.map(list => `${list.seg.start}-${list.seg.end}`), frame: frameValue }, { proxy: false } ); return res.data; } catch (error) { console.error("Error posting segments:", error); return []; } finally { setLoading(false); } }; const postSegments = async () => { if (segments[0]?.start === 0 && segments[0]?.end === 0) return; if (sortableList && filePath) { setLoading(true); const res = await postSeg(); const combinedPrevImg = combinePrevImages(prevImg, res.results); setPrevImg(combinedPrevImg); console.log("Post Request Success"); } }; postSegments(); }, [filePath, segments, frameValue]); const handleModalOpen = useCallback(() => setModalOpen(true), []); const handleModalClose = useCallback(() => { setRemoveImgFiles([]); setModalOpen(false); }, []); const handleDeleteButtonClick = async () => { if (removeImgFiles.length > 0) { setPrevImg([...removeImgFiles]); setRemoveImgFiles([]); } else { const result = await showSwal({ title: "Are you sure delete?", showCancelButton: true, confirmButtonText: "Confirm", cancelButtonText: "Cancel", confirmButtonColor: "#3085d6", cancelButtonColor: "#d33" }); if (result.isConfirmed) { setRemoveImgFiles([...prevImg]); setPrevImg([]); } const success = await Promise.all(removeImgFiles.map(deleteFiles)); return success; } } const handleRemoveFinish = async () => { if (removeImgFiles) { for (const filePath of removeImgFiles) { try { await removeFile(filePath); } catch (e) { console.log("File Remove Error", e); } } } setRemoveImgFiles([]); handleModalClose(); }; return ( <motion.div initial={{ x: width }} animate={{ x: 0 }} exit={{ x: width }} transition={mySpring} > <div style={{ fontSize: 12, padding: "0 5px", color: "var(--gray12)", display: "flex", justifyContent: "space-between", alignItems: "center" }} > <FaAngleRight title={t("Close sidebar")} size={20} className="angle-right" role="button" onClick={toggleSegmentsList} /> {header} <FaExpandArrowsAlt title={t("Image Inspection")} size={18} className="expand-arrow-alt" style={{ cursor: "pointer" }} role="button" onClick={!loading ? handleModalOpen : handleModalClose} /> <Modal title={t("Image Inspection")} centered onCancel={handleModalClose} open={modalOpen} footer={[]} width="100%" > <div className="imagecontainer"> <Button danger className="toggle-remove" onClick={handleDeleteButtonClick}> {removeImgFiles.length > 0 ? "Add" : "Remove"} </Button> {prevImg?.length > 10 && prevImg.map(img => ( <Popover key={img}> {removeImgFiles?.includes(img) ? ( <span> <Result className="result" icon={<FaSmile />} subTitle="delete" /> </span> ) : <Image key={uuidv4()} src={img} preview={{ src: img }} alt={uuidv4()} /> )} </Popover> ))} </div> <Button block onClick={handleRemoveFinish}> Finish </Button> </Modal> </div> ) ``` api 호출을 통해 frameValue 개수(여기서는 12개씩) 만큼 이미지를 렌더링 하고 있는데 두번째 호출부터는 Button이 렌더링되지 않아서 어디가 잘못됐는지 알고싶습니다.. 필요한 부분이 imagecontainer 클래스네임인 div를 렌더링 해야합니다.
개발자
#react
답변 0
댓글 0
조회 85
2년 전 · ㅇ 님의 질문
AI를 활용한 웹사이트,서비스
AI(인공지능)을 활용한 웹사이트 프로젝트를 진행하고 싶은데.. 항상 어떤 주제를 해야할지가 제일 고민이 많고 어려운것 같습니다 chat gpt, AI image..등등 인공지능을 활용한 웹사이트 및 서비스를 주제로 개발하고 싶은데 어떤 아이디어가 있을지.. 아마 기술 스택은 프론트는 vue, javascript, react 중에 사용할 것 같고, 백엔드는 node.js ..? 를 사용할 것 같기도 합니다.. 의견 공유 부탁드려요!
개발자
#react
#javascript
#인공지능
#ai개발
답변 0
댓글 0
조회 229
2년 전 · 비전꿈나무 님의 새로운 댓글
computer vision 꿈나무의 고민
컴퓨터 비전에 관심이 많아 detection, segmentation을 공부 중인 대학교 3학년 학생입니다. 요즘 들어 커리어 패스에 고민이 많습니다. 제가 생각하는 커리어 패스는 남은 학부 2년과 석사 2년입니다. 현재 우리나라에서 cv쪽으로 제대로 되고 있는 분야가 자율주행, 로보틱스, ocr, 카메라 기술 정도라고 생각하고 있습니다. 사실 자율주행이 현재로써는 정말 유망한 사업이긴하지만 언제 어떤 문제로 자율주행의 시대가 끝날지 모른다고 생각합니다. 이러한 걱정을 하는 이유는 cv분야에서 어떤 분야를 잡고 파야할지, 애초에 이런 고민할 필요가 없는건지 감을 못잡겠습니다. 위에서 언급한 대로 예를들어 자율주행으로 대학원까지 한 우물만 팠는데, 자율주행의 시대가 끝난다면 어떡해야 할지 고민이 많습니다. 현재까지 제가 결심한 방향은 취업시장에 뛰어들기 전까지, image recognition(detection, segmentation…) 분야의 최신 논문이나 기술들을 연구하고 공부하면서 대기하고 있으려 합니다. 추천하시는 방향성이나 분야가 있으면 소중한 조언 부탁드리겠습니다.
개발자
#인공지능
#딥러닝
#컴퓨터비전
#진로고민
답변 1
댓글 1
조회 424
2년 전 · 암소메애 님의 새로운 답변
django의 request로 받는 imagefile
안녕하세요. 저는 스타트업회사에서 백엔드 개발자로 근무하고 있습니다! django의 drf 프레임워크를 활용하여 api를 생성하여 사용합니다. 개발을 하던 도중에, 모바일 앱(react-native)에선 사진을 uri, name, type의 필드들로 이루어진 json 객체를 보내는데 이것을 어떤 원리로 django가 사진이라고 이해하고 저장하는지가 궁금합니다 왜냐하면, 기존에 있던 사진들을 s3에 저장된 url 문자열로 frontend에 보내주는데, 그 값을 가지고 다시 uri, type, name으로 쪼개서 다시 백으로 넘겨준다고 하더라고요(기존 사진을 그대로 사용하는 경우) 그런데 그렇게 받은 사진에 대한 객체를 처리하기 전에, s3상에서 그 파일이 삭제가 된 경우에도 정상적으로 작동하는 이유를 모르겠어서 그렇습니다 웹(react)에서는 같은 백 api를 사용하더라도 작동이 안 되고, 앱에서는 작동이 잘 되는데 이것 역시 원인을 잘 모르겠습니다...
개발자
#django
#react
#react-native
#drf
답변 1
댓글 0
조회 64
2년 전 · ㄱㅎㅁ 님의 새로운 답변
web was 분리 실습관련 질문입니다..
안녕하세요. 20살 대학생입니다. web 서버와 was 서버 분리 관련하여 질문드립니다. web과 was의 개념은 조사하였는데, 이를 실 적용하려니 궁금한 사항이 있습니다. web was 개념파악을 위해 아파치와 톰켓을 사용하여 2개의 서버에 나누어 구축하고 있는데 블로그 등을 조사하니 제가 알던 web은 정적처리, was는 동적인 처리 개념이 아닌 was에서 처리를 전부 하면서 web은 그저 리버스 프록시, 정적 파일(html,css,image 등) 적재 등으로만 사용하는 것 같습니다. (즉, web server는 그저 네트워크 장비같은 역할??) 여기서 궁금한 사항입니다. 1. 정적처리, 동적 처리라는 부분을 구현하고 싶다면 페이지 별로 나누어 구성해야 할까요? (원래는 모든 페이지는 web server에 존재하며 was에서는 동적 처리만 구현하도록 하고싶었으나, 단순하게 구현하자면 정적페이지(html)는 web에서 아파치로 바로, 동적 페이지(jsp)는 was에서 구동하는 식으로 진행할까 생각중 입니다. 이렇게 해도 무방한지 궁금합니다.) 2. 프로젝트마다 구성의 차이는 당연히 있겠지만, 요즘 추세로서는 web,was 분리를 어떤식으로 하는지 궁금합니다. (정적,동적 처리 분류 하거나 모두 was에서 담당하고 web은 프록시, 캐싱 역할만 하는지..) 3. 프레임워크(spring, django, flask 등) 을 was 처럼 사용한 경우가 있을까요? (조사해보니 여러 경우가 나오지만 실제로 많이 사용하는지 궁금합니다.) 긴 글 읽어주셔서 너무 감사합니다.
개발자
#web
#was
#apache
#tomcat
답변 1
댓글 0
조회 227
2년 전 · 김현진 님의 답변 업데이트
onChange 함수 관련하여
<template v-for="(item, i) in checkListItem" :key="i"> <label for="camera"> <form> <input type="file" id="camera" accept="image/*" style="display: none" @change="e => handleFileInputChange(e, i, item)" /> </form> </label> </template> <script lang=“ts” setup> const handleFileInputChange = (e, i, item) => { console.log(checkListItem.value) //콘솔1 console.log(item) //콘솔2 console.log(i) //콘솔3 const files = e.target.files[0] const reader = new FileReader() reader.onload = e => { /* 수정필요 */ item[i].check_file = e.target.result item[i].checked = true } reader.readAsDataURL(files) } <script> //콘솔1 checkListItem = [ {checkId: 11, content: ‘체크리스트1’}, {checkId: 12, content: ‘체크리스트2’}, {checkId: 13, content: ‘체크리스트3’}, {checkId: 14, content: ‘체크리스트4’}, {checkId: 15, content: ‘체크리스트5’} ] handleFileInputChange 함수 실행 시 선택한 checkListItem의 item과 index값을 가져와 선택한 item에 파일 첨부하고싶은데.. 현재는 체크리스트4번에 파일을 첨부하면 체크리스트1에 값이 들어옵니다. 콘솔 찍어보면 무조건 첫번째 객체값 부터 찍힙니다. //콘솔2 는 {checkId: 11, content: ‘체크리스트1’}, //콘솔3은 0 이 찍힙니다.
개발자
#onchange
#javascript
#vue3
답변 2
댓글 0
조회 79
2년 전 · 커리어리 AI 봇 님의 새로운 답변
리액트로 스프링과 웹소켓 채팅방을 구현했는데 자동 랜더링이 안됩니다..
안녕하세요! 현재 웹소켓으로 스프링과 채팅기능을 구현중에 있습니다 채팅방에서 채팅을 보내고 받는 건 가능한 상태인데 같이 채팅방에 입장해서 A가 B한테 보냈을 때 B가 페이지를 새로고침 하지 않으면 채팅이 자동 랜더링이 되지 않는 상황인데 여러 방법을 참고하고 해봤지만.. 성공하지 않았습니다 어떻게 풀어나가야 할지 잘 모르겠습니다 ㅠㅠ 코드가 길지만 ... 혹시 답변이 가능할까해서 참고해봅니다 좋은 키워드도 추천해주시면 감사하겠습니다!!... export const ChatRoomPage = () => { //메뉴 모달 const [isModalOpen, setIsModalOpen] = useState(false); const [isExitModalOpen, setIsExitModalOpen] = useState(false); const [backgroundPosition, setBackgroundPosition] = useState('static'); const location = useLocation(); const params = location.pathname; const segments = params.split('/'); const RoomUniqueId = segments[4]; const RoomId = segments[5]; const [messageData, setMessageData] = useState([]); const [messageList, setMessageList] = useState([]); const [message, setMessage] = useState(''); const accesskey = Cookies.get('Access_key'); // 채팅방 입장시 안내 문구 기능 const [showModal, setShowModal] = useState(false); const client = useRef({}); useEffect(() => { console.log('유즈이펙트 쉴행'); setShowModal(true); connect('L'); return () => disconnect(); }, []); const connect = type => { client.current = new StompJs.Client({ brokerURL: 'ws://222.102.175.141:8081/ws-stomp', connectHeaders: { Access_key: `Bearer ${accesskey}`, }, debug: function (str) { console.log('str ::', str); }, onConnect: () => { if (type === 'L') { subscribe(); publish(); } else { subscribe1(); publish1(); } }, }); client.current.webSocketFactory = function () { return new SockJS('http://222.102.175.141:8081/ws-stomp'); }; client.current.activate(); return () => disconnect(); }; const subscribe = () => { client.current.subscribe(`/sub/chat/messageList/${localStorage.memberUniqueId}`, message => { // console.log('messageData11 : ', JSON.parse(`${message.body}`)); setMessageData(JSON.parse(`${message.body}`)); const data = JSON.parse(`${message.body}`); setMessageList(data.data.chatMessageList); }); }; const publish = () => { client.current.publish({ destination: `/pub/chat/messageList/${localStorage.memberUniqueId}`, body: JSON.stringify({ chatRoomId: RoomId, chatRoomUniqueId: RoomUniqueId, page: 0, }), }); }; const closeModal = () => { setIsModalOpen(false); setBackgroundPosition('static'); }; const openModal = () => { setIsModalOpen(true); setBackgroundPosition('fixed'); }; const handleBackdropClick = e => { console.log('e ::', e); if (e.target === e.currentTarget) { closeModal(); } }; const ExitopenModal = () => { setIsExitModalOpen(true); }; const ExitcloseModal = () => { setIsExitModalOpen(false); }; const ReportButtonHandler = () => { alert('곧 업데이트 예정입니다!'); }; // 채팅 보내기 const sendMessage = message => { console.log('message :: ', message); connect(); setMessage(''); return () => disconnect(); }; const subscribe1 = () => { client.current.subscribe(`/sub/chat/message/${RoomUniqueId}`, message => { setMessageData({ ...messageList, message }); }); }; const publish1 = () => { client.current.publish({ destination: `/pub/chat/message/${RoomUniqueId}`, body: JSON.stringify({ memberId: `${localStorage.memberId}`, memberName: `${localStorage.memberName}`, memberUniqueId: `${localStorage.memberUniqueId}`, memberProfileImage: `${localStorage.profileImage}`, chatRoomId: RoomId, chatRoomUniqueId: RoomUniqueId, message: message, }), }); }; const disconnect = () => { client.current.deactivate(); }; console.log('messageList :: ', messageList); return ( <> <div style={{ width: '100%', height: '100%', position: backgroundPosition, }} > <Background> <Topbar> <Link to={`${PATH_URL.PARTY_CHAT}/${localStorage.memberUniqueId}`}> <TopBackDiv> <LeftBack /> </TopBackDiv> </Link> <TopbarName>모임이름</TopbarName> <ModalBtn onClick={() => { openModal(); }} > <RoomMenuIcon /> </ModalBtn> </Topbar> <Container> <Contents> <ParticipantDiv>ㅇㅇㅇ님이 참여했습니다.</ParticipantDiv> {messageList?.map((data, index) => { return ( <OtherDiv key={index}> <div style={{ position: 'relative', }} > <OtherImg> <OtherProfile> <img src={data.memberProfileImage} alt="profile" style={{ width: '100%', height: '100%', borderRadius: '8px', }} /> </OtherProfile> <OtherHostIcon> <PartHostIcon /> </OtherHostIcon> </OtherImg> <OthertInfo> <OtherName>{data.sender}</OtherName> <OtherContents> <OtherChatText>{data.message}</OtherChatText> <OtherChatTime>12:19 pm</OtherChatTime> </OtherContents> </OthertInfo> </div> </OtherDiv> ); })}
개발자
#채팅
#웹소켓
#채팅기능
답변 2
댓글 0
조회 607