jebin2 commited on
Commit
f204a08
Β·
1 Parent(s): 0f2dbed
Files changed (3) hide show
  1. image/convert.html +1 -0
  2. image/converter.py +64 -14
  3. image/image_base.py +2 -1
image/convert.html CHANGED
@@ -520,6 +520,7 @@
520
  <option value="jpg">JPG</option>
521
  <option value="png">PNG</option>
522
  <option value="webp">WebP</option>
 
523
  </select>
524
  </div>
525
  </div>
 
520
  <option value="jpg">JPG</option>
521
  <option value="png">PNG</option>
522
  <option value="webp">WebP</option>
523
+ <option value="svg">SVG</option>
524
  </select>
525
  </div>
526
  </div>
image/converter.py CHANGED
@@ -8,6 +8,8 @@ and aspect ratio during format conversion. Supports all major image formats.
8
  from .image_base import ImageBase
9
  from PIL import Image
10
  import os
 
 
11
  from typing import Dict, Optional, Tuple
12
  from custom_logger import logger_config
13
  import pillow_heif
@@ -165,6 +167,49 @@ class Converter(ImageBase):
165
 
166
  return converted_image
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
  def _verify_conversion_quality(self, original_size: Tuple[int, int], output_path: str) -> bool:
169
  """
170
  Verify that the converted image maintains original quality and dimensions.
@@ -238,20 +283,25 @@ class Converter(ImageBase):
238
  # Generate output path
239
  output_path = self._generate_output_path(output_format)
240
 
241
- # Get optimal save settings
242
- save_settings = self._get_optimal_save_settings(target_format)
243
-
244
- # Preserve metadata
245
- metadata = self._preserve_metadata(original_image, target_format)
246
- save_settings.update(metadata)
247
-
248
- logger_config.info(f"Converting to {target_format} with maximum quality")
249
-
250
- # Perform conversion with quality preservation
251
- converted_image.save(output_path, format=target_format, **save_settings)
252
-
253
- # Verify conversion quality
254
- self._verify_conversion_quality(original_size, output_path)
 
 
 
 
 
255
 
256
  logger_config.info(f"βœ“ Conversion completed successfully: {output_path}")
257
  return output_path
 
8
  from .image_base import ImageBase
9
  from PIL import Image
10
  import os
11
+ import base64
12
+ import io
13
  from typing import Dict, Optional, Tuple
14
  from custom_logger import logger_config
15
  import pillow_heif
 
167
 
168
  return converted_image
169
 
170
+ def _convert_to_svg(self, image: Image.Image, output_path: str, original_size: Tuple[int, int]) -> None:
171
+ """
172
+ Convert a raster image to SVG by embedding it as a base64-encoded image.
173
+
174
+ Args:
175
+ image: PIL Image object
176
+ output_path: Path to save the SVG file
177
+ original_size: Original image dimensions (width, height)
178
+ """
179
+ # Convert image to PNG bytes for embedding
180
+ buffer = io.BytesIO()
181
+
182
+ # Ensure we save in a format that preserves transparency
183
+ if image.mode in ('RGBA', 'LA', 'P'):
184
+ image.save(buffer, format='PNG', optimize=False)
185
+ mime_type = 'image/png'
186
+ else:
187
+ image.save(buffer, format='PNG', optimize=False)
188
+ mime_type = 'image/png'
189
+
190
+ buffer.seek(0)
191
+ image_base64 = base64.b64encode(buffer.getvalue()).decode('utf-8')
192
+
193
+ width, height = original_size
194
+
195
+ # Create SVG with embedded image
196
+ svg_content = f'''<?xml version="1.0" encoding="UTF-8"?>
197
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
198
+ width="{width}" height="{height}" viewBox="0 0 {width} {height}">
199
+ <image width="{width}" height="{height}"
200
+ xlink:href="data:{mime_type};base64,{image_base64}"/>
201
+ </svg>'''
202
+
203
+ with open(output_path, 'w', encoding='utf-8') as f:
204
+ f.write(svg_content)
205
+
206
+ # Verify file was created
207
+ if not os.path.exists(output_path):
208
+ raise Exception("SVG file was not created")
209
+
210
+ file_size = os.path.getsize(output_path)
211
+ logger_config.info(f"βœ“ SVG file created: {file_size:,} bytes")
212
+
213
  def _verify_conversion_quality(self, original_size: Tuple[int, int], output_path: str) -> bool:
214
  """
215
  Verify that the converted image maintains original quality and dimensions.
 
283
  # Generate output path
284
  output_path = self._generate_output_path(output_format)
285
 
286
+ # Handle SVG conversion specially
287
+ if target_format == 'SVG':
288
+ logger_config.info(f"Converting to SVG (embedding as base64)")
289
+ self._convert_to_svg(converted_image, output_path, original_size)
290
+ else:
291
+ # Get optimal save settings
292
+ save_settings = self._get_optimal_save_settings(target_format)
293
+
294
+ # Preserve metadata
295
+ metadata = self._preserve_metadata(original_image, target_format)
296
+ save_settings.update(metadata)
297
+
298
+ logger_config.info(f"Converting to {target_format} with maximum quality")
299
+
300
+ # Perform conversion with quality preservation
301
+ converted_image.save(output_path, format=target_format, **save_settings)
302
+
303
+ # Verify conversion quality
304
+ self._verify_conversion_quality(original_size, output_path)
305
 
306
  logger_config.info(f"βœ“ Conversion completed successfully: {output_path}")
307
  return output_path
image/image_base.py CHANGED
@@ -21,7 +21,8 @@ class ImageBase(MainBase):
21
  'tif': 'TIFF',
22
  'bmp': 'BMP',
23
  'gif': 'GIF',
24
- 'heic': 'HEIC'
 
25
  }
26
 
27
  # Create directories if they don't exist
 
21
  'tif': 'TIFF',
22
  'bmp': 'BMP',
23
  'gif': 'GIF',
24
+ 'heic': 'HEIC',
25
+ 'svg': 'SVG'
26
  }
27
 
28
  # Create directories if they don't exist