├── .gitignore ├── LICENSE ├── ReadMe.md ├── assets ├── logo.png └── og.png ├── index.html ├── package-lock.json ├── package.json ├── script.js └── style.css /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore all files starting with . or ~ 2 | .* 3 | ~* 4 | 5 | # ignore node/grunt dependency directories 6 | node_modules/ 7 | 8 | # Ignore /build directory. 9 | /build 10 | 11 | # ignore composer vendor directory 12 | /vendor 13 | 14 | # ignore components loaded via Bower 15 | /bower_components 16 | 17 | # ignore jekyll build directory 18 | /_site 19 | 20 | # ignore OS generated files 21 | ehthumbs.db 22 | Thumbs.db 23 | 24 | # ignore Editor files 25 | *.sublime-project 26 | *.sublime-workspace 27 | *.komodoproject 28 | 29 | # ignore log files and databases 30 | *.log 31 | *.sql 32 | *.sqlite 33 | 34 | # ignore compiled files 35 | *.com 36 | *.class 37 | *.dll 38 | *.exe 39 | *.o 40 | *.so 41 | 42 | # ignore packaged files 43 | *.7z 44 | *.dmg 45 | *.gz 46 | *.iso 47 | *.jar 48 | *.rar 49 | *.tar 50 | *.zip 51 | 52 | # ignore private/secret files 53 | *.der 54 | *.key 55 | *.pem 56 | 57 | # -------------------------------------------------------- 58 | # BEGIN Explictly Allowed Files (i.e. do NOT ignore these) 59 | # -------------------------------------------------------- 60 | 61 | # track these files, if they exist 62 | !.editorconfig 63 | !.env.example 64 | !.gitignore 65 | !.nvmrc 66 | !.phpcs.xml.dist -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Vishwa Gaurav 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ReadMe.md: -------------------------------------------------------------------------------- 1 | # YASIC - Yet Another Simple Image Converter 2 | Convert & Resize your images into PNG, JPG, BMP, WEBP and more using YASIC (Yet Another Simple Image Converter 🔥) 3 | 4 | Website: [yasic.vercel.app](https://yasic.vercel.app) 5 | 6 | ![yasic](https://user-images.githubusercontent.com/81325730/198853279-7f2457a3-861c-4cbb-a70f-da981f3641a2.png) 7 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VishwaGauravIn/yet-another-simple-image-converter/8a0ec855f1994ea3d9f0c9c97cae15230ce576e7/assets/logo.png -------------------------------------------------------------------------------- /assets/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VishwaGauravIn/yet-another-simple-image-converter/8a0ec855f1994ea3d9f0c9c97cae15230ce576e7/assets/og.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | YASIC - Yet Another Simple Image Converter 8 | 9 | 10 | 11 | 12 | 13 | 14 | 18 | 19 | 23 | 24 | 25 | 29 | 30 | 31 | 32 | 36 | 40 | 44 | 45 | 46 | 50 | 54 | 58 | 59 | 60 | 61 | 86 | 87 |
88 |
89 | 90 | 91 | 108 | 115 |
116 |
117 |

Editor

118 | 119 |

Resolution:

120 | 128 | 136 |
137 | 138 |

Maintain aspect ratio:

139 |
140 | 147 | 163 |
164 |
165 | 166 | 167 |

Format:

168 |
169 |
170 | 178 | 179 | PNG 180 |
181 | 182 |
183 | 190 | 191 | JPG 192 |
193 |
194 | 201 | 202 | BMP 203 |
204 | 205 |
206 | 213 | 214 | WEBP 215 |
216 |
217 |
218 | 219 | 220 |

File Name:

221 | 228 |
229 | 230 | 247 |
248 |
249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yet-another-simple-image-converter", 3 | "lockfileVersion": 2, 4 | "requires": true, 5 | "packages": { 6 | "": { 7 | "dependencies": { 8 | "image-converter-pro": "^1.0.2" 9 | } 10 | }, 11 | "node_modules/image-converter-pro": { 12 | "version": "1.0.2", 13 | "resolved": "https://registry.npmjs.org/image-converter-pro/-/image-converter-pro-1.0.2.tgz", 14 | "integrity": "sha512-ORhGqgxyj0a1LTXjR/YLMKNJWShWf8aXKXFOoQmF5vbiQiu0Zn+U+gNijH4P/8Qv+Cywih3LsYYElnOLLecfqg==" 15 | } 16 | }, 17 | "dependencies": { 18 | "image-converter-pro": { 19 | "version": "1.0.2", 20 | "resolved": "https://registry.npmjs.org/image-converter-pro/-/image-converter-pro-1.0.2.tgz", 21 | "integrity": "sha512-ORhGqgxyj0a1LTXjR/YLMKNJWShWf8aXKXFOoQmF5vbiQiu0Zn+U+gNijH4P/8Qv+Cywih3LsYYElnOLLecfqg==" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "image-converter-pro": "^1.0.2" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /script.js: -------------------------------------------------------------------------------- 1 | // Constants 2 | const fileInput = document.getElementById("file_selector"); 3 | const fileName = document.getElementById("filename"); 4 | const prevImg = document.getElementById("prevImg"); 5 | const inpWidth = document.getElementById("width"); 6 | const inpHeight = document.getElementById("height"); 7 | 8 | // Variables 9 | let realWidth = prevImg.clientWidth; 10 | let realHeight = prevImg.clientHeight; 11 | let format = "png"; 12 | 13 | function selFile() { 14 | fileInput.click(); 15 | } 16 | 17 | function fileSelected() { 18 | if (fileInput.files.length !== 0) { 19 | // Selecting the first file 20 | const [file] = fileInput.files; 21 | // removing the file extension from name 22 | fileName.value = file.name.replace(/\.[^.]*$/, ""); 23 | // setting file name 24 | prevImg.src = URL.createObjectURL(file); 25 | // updating new height and width 26 | setTimeout(() => { 27 | realWidth = prevImg.clientWidth; 28 | realHeight = prevImg.clientHeight; 29 | // setting height and width input value 30 | inpHeight.value = realHeight; 31 | inpWidth.value = realWidth; 32 | }, 100); 33 | } 34 | } 35 | 36 | function onWChange() { 37 | inpHeight.value = (inpWidth.value / realWidth) * realHeight; 38 | } 39 | 40 | function onHChange() { 41 | inpWidth.value = (inpHeight.value / realHeight) * realWidth; 42 | } 43 | 44 | function changeFormat(f) { 45 | format = f; 46 | } 47 | 48 | function downloadFile() { 49 | if (inpHeight.value > 8000 || inpWidth.value > 8000) { 50 | alert("Height or Width can not be greater than 8000px"); 51 | } else { 52 | imgConverter( 53 | prevImg.src, 54 | realWidth, 55 | realHeight, 56 | format, 57 | inpHeight.value / realHeight 58 | ).then((dataUri) => { 59 | const a = document.createElement("a"); 60 | a.href = dataUri; 61 | a.style.display = "none"; 62 | a.download = fileName.value + "." + format || "spiffy" + "." + format; 63 | a.click(); 64 | }); 65 | } 66 | } 67 | 68 | // via: https://www.npmjs.com/package/image-converter-pro 69 | const imgConverter = ( 70 | Dataurl, 71 | width = 500, 72 | height = 500, 73 | format = "png", 74 | scale = 1 75 | ) => 76 | new Promise((resolve, reject) => { 77 | let canvas; 78 | let ctx; 79 | let img; 80 | 81 | img = new Image(); 82 | img.src = Dataurl; 83 | img.onload = () => { 84 | canvas = document.createElement("canvas"); 85 | canvas.width = img.width * scale; 86 | canvas.height = img.height * scale; 87 | ctx = canvas.getContext("2d"); 88 | ctx.drawImage( 89 | img, 90 | 0, 91 | 0, 92 | img.width, 93 | img.height, 94 | 0, 95 | 0, 96 | width * scale, 97 | height * scale 98 | ); 99 | 100 | img = new Image(); 101 | img.src = canvas.toDataURL(`image/${format}`); 102 | img.onload = () => { 103 | canvas = document.createElement("canvas"); 104 | canvas.width = width * scale; 105 | canvas.height = height * scale; 106 | ctx = canvas.getContext("2d"); 107 | ctx.drawImage(img, 0, 0); 108 | resolve(canvas.toDataURL(`image/${format}`)); 109 | }; 110 | }; 111 | }); 112 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary-light: #8abdff; 3 | --primary: #6d5dfc; 4 | --primary-dark: #5b0eeb; 5 | --white: #ffffff; 6 | --greyLight-1: #e4ebf5; 7 | --greyLight-2: #c8d0e7; 8 | --greyLight-3: #bec8e4; 9 | --greyDark: #9baacf; 10 | } 11 | 12 | /* Applying poppins font to html */ 13 | html { 14 | font-family: "Poppins", sans-serif; 15 | background-color: #e4ebf5; 16 | } 17 | 18 | * { 19 | padding: 0; 20 | margin: 0; 21 | } 22 | 23 | .navbar { 24 | padding: 1rem; 25 | display: flex; 26 | justify-content: center; 27 | align-items: center; 28 | color: var(--primary); 29 | } 30 | 31 | .title { 32 | font-family: "Cinzel Decorative", cursive; 33 | letter-spacing: 0.3rem; 34 | font-size: 2rem; 35 | } 36 | 37 | /* BUTTONS */ 38 | .btn { 39 | padding: 1rem; 40 | padding-left: 2rem; 41 | padding-right: 2rem; 42 | border-radius: 9999rem; 43 | border: none; 44 | box-shadow: 0.3rem 0.3rem 0.6rem var(--greyLight-2), 45 | -0.2rem -0.2rem 0.5rem var(--white); 46 | justify-self: center; 47 | display: flex; 48 | align-items: center; 49 | justify-content: center; 50 | cursor: pointer; 51 | transition: 0.3s ease; 52 | transition: all 0.35s ease-in-out; 53 | text-decoration: none; 54 | } 55 | .btn__primary { 56 | grid-column: 1/2; 57 | grid-row: 4/5; 58 | align-self: center; 59 | margin-top: 2rem; 60 | background: var(--primary); 61 | box-shadow: inset 0.2rem 0.2rem 1rem var(--primary-light), 62 | inset -0.2rem -0.2rem 1rem var(--primary-dark), 63 | 0.3rem 0.3rem 0.6rem var(--greyLight-2), -0.2rem -0.2rem 0.5rem var(--white); 64 | color: var(--greyLight-1); 65 | font-weight: 500; 66 | font-size: 1rem; 67 | letter-spacing: 0.1rem; 68 | } 69 | .btn__primary:hover { 70 | color: var(--white); 71 | } 72 | .btn__primary:active { 73 | box-shadow: inset 0.2rem 0.2rem 1rem var(--primary-dark), 74 | inset -0.2rem -0.2rem 1rem var(--primary-light); 75 | } 76 | .btn__secondary { 77 | grid-column: 1/2; 78 | grid-row: 5/6; 79 | color: var(--greyDark); 80 | position: absolute; 81 | right: 1rem; 82 | font-weight: 500; 83 | font-size: 1rem; 84 | letter-spacing: 0.1rem; 85 | } 86 | .btn__secondary:hover { 87 | color: var(--primary); 88 | } 89 | .btn__secondary:active { 90 | box-shadow: inset 0.2rem 0.2rem 0.5rem var(--greyLight-2), 91 | inset -0.2rem -0.2rem 0.5rem var(--white); 92 | } 93 | .btn p { 94 | font-size: 1.6rem; 95 | } 96 | .ext-link { 97 | width: 1rem; 98 | margin-left: 0.2rem; 99 | } 100 | 101 | /* Main */ 102 | .parent { 103 | display: flex; 104 | justify-content: center; 105 | align-items: center; 106 | padding: 1rem; 107 | position: relative; 108 | } 109 | 110 | .div1 { 111 | display: flex; 112 | flex-direction: column; 113 | flex: 0.6; 114 | padding: 1rem; 115 | justify-content: center; 116 | align-items: center; 117 | } 118 | .div2 { 119 | display: flex; 120 | flex-direction: column; 121 | flex: 0.4; 122 | padding: 1rem; 123 | } 124 | 125 | .div1 img { 126 | max-width: 90%; 127 | border-radius: 1%; 128 | } 129 | 130 | /* FORM */ 131 | .form { 132 | grid-column: 3/4; 133 | grid-row: 3/4; 134 | } 135 | .form__input { 136 | width: 100%; 137 | height: 3rem; 138 | border: none; 139 | border-radius: 1rem; 140 | font-size: 1.4rem; 141 | padding-left: 1.4rem; 142 | padding-right: 1.4rem; 143 | box-shadow: inset 0.2rem 0.2rem 0.5rem var(--greyLight-2), 144 | inset -0.2rem -0.2rem 0.5rem var(--white); 145 | background: none; 146 | font-family: inherit; 147 | color: var(--greyDark); 148 | } 149 | .form__input::-moz-placeholder { 150 | color: var(--greyLight-3); 151 | } 152 | .form__input:-ms-input-placeholder { 153 | color: var(--greyLight-3); 154 | } 155 | .form__input::placeholder { 156 | color: var(--greyLight-3); 157 | } 158 | .form__input:focus { 159 | outline: none; 160 | box-shadow: 0.3rem 0.3rem 0.6rem var(--greyLight-2), 161 | -0.2rem -0.2rem 0.5rem var(--white); 162 | } 163 | 164 | .span1 { 165 | display: flex; 166 | flex-wrap: wrap; 167 | gap: 1rem; 168 | align-items: center; 169 | margin-top: 2rem; 170 | font-weight: 500; 171 | } 172 | 173 | .span2 { 174 | align-items: initial; 175 | } 176 | 177 | /* CHECKBOX */ 178 | .checkbox__1 { 179 | display: flex; 180 | justify-content: center; 181 | } 182 | .checkbox__1 input { 183 | width: 0px; 184 | height: 0px; 185 | opacity: 0; 186 | } 187 | .checkbox__1 label { 188 | box-shadow: 0.3rem 0.3rem 0.6rem var(--greyLight-2), 189 | -0.2rem -0.2rem 0.5rem var(--white); 190 | position: relative; 191 | cursor: not-allowed; 192 | display: flex; 193 | justify-content: center; 194 | align-items: center; 195 | border-radius: 0.5rem; 196 | width: 2rem; 197 | height: 2rem; 198 | } 199 | .checkbox__1 label:hover svg { 200 | color: var(--primary); 201 | } 202 | .checkbox__1 label svg { 203 | width: 75%; 204 | color: var(--greyDark); 205 | transition: 0.3s ease; 206 | } 207 | .checkbox__1 input:checked ~ label { 208 | box-shadow: inset 0.2rem 0.2rem 0.5rem var(--greyLight-2), 209 | inset -0.2rem -0.2rem 0.5rem var(--white); 210 | } 211 | .checkbox__1 input:checked ~ label svg { 212 | color: var(--primary); 213 | } 214 | 215 | /* RADIO */ 216 | .radio { 217 | display: flex; 218 | flex-direction: column; 219 | justify-items: center; 220 | gap: 1rem; 221 | } 222 | .radio input { 223 | display: none; 224 | } 225 | .radio__1, 226 | .radio__2, 227 | .radio__3, 228 | .radio__4 { 229 | display: flex; 230 | gap: 1rem; 231 | align-items: center; 232 | } 233 | .radio__1 input:checked ~ label, 234 | .radio__2 input:checked ~ label, 235 | .radio__3 input:checked ~ label, 236 | .radio__4 input:checked ~ label { 237 | box-shadow: inset 0.2rem 0.2rem 0.5rem var(--greyLight-2), 238 | inset -0.2rem -0.2rem 0.5rem var(--white); 239 | } 240 | .radio__1 input:checked ~ label::after, 241 | .radio__2 input:checked ~ label::after, 242 | .radio__3 input:checked ~ label::after, 243 | .radio__4 input:checked ~ label::after { 244 | background: var(--primary); 245 | } 246 | .radio__1 label, 247 | .radio__2 label, 248 | .radio__3 label, 249 | .radio__4 label { 250 | box-shadow: 0.3rem 0.3rem 0.6rem var(--greyLight-2), 251 | -0.2rem -0.2rem 0.5rem var(--white); 252 | position: relative; 253 | display: flex; 254 | justify-content: center; 255 | align-items: center; 256 | cursor: pointer; 257 | width: 2rem; 258 | height: 2rem; 259 | border-radius: 50%; 260 | } 261 | .radio__1 label:hover::after, 262 | .radio__2 label:hover::after, 263 | .radio__3 label:hover::after, 264 | .radio__4 label:hover::after { 265 | background: var(--primary); 266 | } 267 | .radio__1 label::after, 268 | .radio__2 label::after, 269 | .radio__3 label::after, 270 | .radio__4 label::after { 271 | content: ""; 272 | position: absolute; 273 | width: 1rem; 274 | height: 1rem; 275 | background: var(--greyDark); 276 | border-radius: 50%; 277 | transition: 0.3s ease; 278 | } 279 | 280 | /* File Selector */ 281 | 282 | #file_selector { 283 | display: none; 284 | } 285 | 286 | /* Media Queries */ 287 | @media screen and (max-width: 600px) { 288 | .navbar { 289 | justify-content: left; 290 | } 291 | .parent { 292 | flex-direction: column; 293 | } 294 | } 295 | --------------------------------------------------------------------------------