Skip to content

Commit 3b6da9e

Browse files
committed
Added: README.md, fixed image processing and updated README.md
1 parent 22265cb commit 3b6da9e

22 files changed

+362
-163
lines changed

.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
NODE_ENV=development
2+
23
NEXT_PUBLIC_AWS_S3_REGION=us-east-1
3-
NEXT_PUBLIC_AWS_S3_BUCKET_NAME=your-bucket-name
4+
NEXT_PUBLIC_AWS_S3_BUCKET_NAME=server-bucket-name
5+
NEXT_PUBLIC_AWS_S3_STORAGE_BUCKET_NAME=storage-bucket-name
46
AWS_ACCESS_KEY_ID=key
57
AWS_SECRET_ACCESS_KEY=secret
68
AWS_CLOUDFRONT_DISTRIBUTION=abcdef12345678.cloudfront.net

README.md

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
1-
# S3 Asset Uploader with Sharp optimization
1+
# S3 Image Manager
22

3-
Simple S3 image asset uploader with Sharp optimization. It is very simple and barebones, but it does the job.
4-
- In future I plan to extend this to also support videos and documents.
3+
This simple S3 image manager allows you to:
4+
- Optimize images with Sharp
5+
- Change quality
6+
- Change format
7+
- Resize
8+
- Clone (to create multiple versions of the same image)
9+
- Download processed images
10+
- Upload images to S3
11+
- Search images in S3
12+
- Delete images in S3
513

614
Run it on localhost to optimize and upload images to S3. Retrieved links of uploaded images point to Cloudfront and can be used in production.
715

816
## Preview
9-
<img src="assets/preview.png" alt="App Preview" width="800"/>
17+
18+
### Modification
19+
![Modify](assets/modify.png)
20+
21+
### Upload/Download
22+
![Upload/Download](assets/upload-download.png)
23+
24+
### S3 for serving images
25+
![S3 Server](assets/s3-server.png)
26+
27+
## S3 for storing images
28+
![S3 Storage](assets/s3-storage.png)
1029

1130
## Pre-requisites
1231

13-
1) Setup S3 bucket with Cloudfront distribution in front of it. This app returns Cloudfront links after you upload the image. [This video](https://www.youtube.com/watch?v=kbI7kRWAU-w) can help you with that.
14-
2) Create IAM user with following policy (replace "your-bucket-name" with your actual bucket name)
32+
1) Setup two AWS S3 buckets - one is for serving images (server-bucket) via Cloudfront distribution (CDN) and second is for storing raw images (storage-bucket)
33+
- <small>S3 bucket for storage is optional</small>
34+
- <small>Make sure to enable versioning in your S3 buckets, otherwise you might accidentally delete your images</small>
35+
- <small>[How to setup a Cloudfront distribution](https://www.youtube.com/watch?v=kbI7kRWAU-w)</small>
36+
2) Create IAM user with following policy (replace "server-bucket-name" and "storage-bucket-name" with your actual bucket name)
1537
```
1638
{
1739
"Version": "2012-10-17",
@@ -25,8 +47,10 @@ Run it on localhost to optimize and upload images to S3. Retrieved links of uplo
2547
"s3:ListBucket"
2648
],
2749
"Resource": [
28-
"arn:aws:s3:::blazing-peon-images",
29-
"arn:aws:s3:::blazing-peon-images/*"
50+
"arn:aws:s3:::server-bucket-name",
51+
"arn:aws:s3:::server-bucket-name/*",
52+
"arn:aws:s3:::storage-bucket-name/*",
53+
"arn:aws:s3:::storage-bucket-name/*"
3054
]
3155
}
3256
]
@@ -50,3 +74,6 @@ Run it on localhost to optimize and upload images to S3. Retrieved links of uplo
5074
- <small>#2 Upload Form</small>
5175
5) **Fill in the new image name** (technically S3 namespace) <small>-> it will be automatically prefixed with assets/</small>
5276
6) **Click upload** <small>-> image will be uploaded to S3 bucket and Cloudfront link will be returned</small>
77+
78+
## Notes
79+
1) Animations / GIFs are not supported

assets/modify.png

539 KB
Loading

assets/preview.png

-697 KB
Binary file not shown.

assets/s3-server.png

66.1 KB
Loading

assets/s3-storage.png

45.7 KB
Loading

assets/upload-download.png

647 KB
Loading

pnpm-lock.yaml

Lines changed: 34 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/api/modify/route.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,21 +71,35 @@ async function processImage(
7171
outputFormat = metadata.format;
7272
quality = 100;
7373
} else {
74-
outputHeight = imageInfo.height ?? metadata.height;
75-
outputWidth = imageInfo.width ?? metadata.width;
74+
if (!imageInfo.height && !imageInfo.width) {
75+
outputHeight = metadata.height;
76+
outputWidth = metadata.width;
77+
} else {
78+
outputHeight =
79+
imageInfo.height && imageInfo.height > 0 ? imageInfo.height : undefined;
80+
outputWidth =
81+
imageInfo.width && imageInfo.width > 0 ? imageInfo.width : undefined;
82+
}
83+
7684
outputFormat = imageInfo.format ?? metadata.format;
7785
quality = imageInfo.quality;
7886
}
7987

80-
// Process image with sharp
81-
const processedImageBuffer = raw
82-
? await image.toBuffer()
83-
: await image
84-
.resize(outputWidth, outputHeight)
85-
.toFormat(outputFormat as keyof sharp.FormatEnum, {
86-
quality,
87-
})
88-
.toBuffer();
88+
if (!raw) {
89+
image
90+
.resize(outputWidth, outputHeight)
91+
.toFormat(outputFormat as keyof sharp.FormatEnum, {
92+
quality,
93+
});
94+
}
95+
96+
const { data: processedImageBuffer, info } = await image.toBuffer({
97+
resolveWithObject: true,
98+
});
99+
100+
outputHeight = info.height;
101+
outputWidth = info.width;
102+
outputFormat = info.format;
89103

90104
return {
91105
title: outputTitle,

src/app/api/objects/route.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ const s3Client = new S3Client({
1111

1212
export async function GET(request: Request) {
1313
const url = new URL(request.url);
14-
const type = url.searchParams.get("type") ?? "server";
14+
// NEXT_PUBLIC_AWS_S3_STORAGE_BUCKET_NAME is optional
15+
const type = !process.env.NEXT_PUBLIC_AWS_S3_STORAGE_BUCKET_NAME
16+
? "server"
17+
: (url.searchParams.get("type") ?? "server");
1518

1619
let bucketName;
1720
let prefix;

0 commit comments

Comments
 (0)