@@ -260,21 +260,6 @@ def from_filename(klass, filename):
260260 file_map = klass .filespec_to_file_map (filename )
261261 return klass .from_file_map (file_map )
262262
263- @classmethod
264- def from_bytes (klass , bstring ):
265- """ Construct image from a byte string
266-
267- Class method
268-
269- Parameters
270- ----------
271- bstring : bytes
272- Byte string containing the on-disk representation of an image
273- """
274- bio = io .BytesIO (bstring )
275- file_map = self .make_file_map ({'image' : bio , 'header' : bio })
276- return klass .from_file_map (file_map )
277-
278263 @classmethod
279264 def from_file_map (klass , file_map ):
280265 raise NotImplementedError
@@ -349,24 +334,6 @@ def to_filename(self, filename):
349334 self .file_map = self .filespec_to_file_map (filename )
350335 self .to_file_map ()
351336
352- def to_bytes (self ):
353- """ Return a ``bytes`` object with the contents of the file that would
354- be written if the image were saved.
355-
356- Parameters
357- ----------
358- None
359-
360- Returns
361- -------
362- bytes
363- Serialized image
364- """
365- bio = io .BytesIO ()
366- file_map = self .make_file_map ({'image' : bio , 'header' : bio })
367- self .to_file_map (file_map )
368- return bio .getvalue ()
369-
370337 @deprecate_with_version ('to_filespec method is deprecated.\n '
371338 'Please use the "to_filename" method instead.' ,
372339 '1.0' , '3.0' )
@@ -545,3 +512,79 @@ def path_maybe_image(klass, filename, sniff=None, sniff_max=1024):
545512 if sniff is None or len (sniff [0 ]) < klass ._meta_sniff_len :
546513 return False , sniff
547514 return klass .header_class .may_contain_header (sniff [0 ]), sniff
515+
516+
517+ class SerializableImage (FileBasedImage ):
518+ '''
519+ Abstract image class for (de)serializing images to/from byte strings.
520+
521+ The class doesn't define any image properties.
522+
523+ It has:
524+
525+ methods:
526+
527+ * .to_bytes() - serialize image to byte string
528+
529+ classmethods:
530+
531+ * from_bytes(bytestring) - make instance by deserializing a byte string
532+
533+ The following properties should hold:
534+
535+ * ``klass.from_bytes(bstr).to_bytes() == bstr``
536+ * if ``img = orig.__class__.from_bytes(orig.to_bytes())``, then
537+ ``img.header == orig.header`` and ``img.get_data() == orig.get_data()``
538+
539+ Further, for images that are single files on disk, the following methods of loading
540+ the image must be equivalent:
541+
542+ img = klass.from_filename(fname)
543+
544+ with open(fname, 'rb') as fobj:
545+ img = klass.from_bytes(fobj.read())
546+
547+ And the following methods of saving a file must be equivalent:
548+
549+ img.to_filename(fname)
550+
551+ with open(fname, 'wb') as fobj:
552+ fobj.write(img.to_bytes())
553+
554+ Images that consist of separate header and data files will generally
555+ place the header with the data, but if the header is not of fixed
556+ size and does not define its own size, a new format may need to be
557+ defined.
558+ '''
559+ @classmethod
560+ def from_bytes (klass , bytestring ):
561+ """ Construct image from a byte string
562+
563+ Class method
564+
565+ Parameters
566+ ----------
567+ bstring : bytes
568+ Byte string containing the on-disk representation of an image
569+ """
570+ bio = io .BytesIO (bstring )
571+ file_map = klass .make_file_map ({'image' : bio , 'header' : bio })
572+ return klass .from_file_map (file_map )
573+
574+ def to_bytes (self ):
575+ """ Return a ``bytes`` object with the contents of the file that would
576+ be written if the image were saved.
577+
578+ Parameters
579+ ----------
580+ None
581+
582+ Returns
583+ -------
584+ bytes
585+ Serialized image
586+ """
587+ bio = io .BytesIO ()
588+ file_map = self .make_file_map ({'image' : bio , 'header' : bio })
589+ self .to_file_map (file_map )
590+ return bio .getvalue ()
0 commit comments