class ImageTexture(ContentModel): """Contains an image that can be mapped to a point set or surface""" origin = properties.Vector3('Origin point of the texture', default=[0., 0., 0.]) axis_u = properties.Vector3('Vector corresponding to the image x-axis', default='X') axis_v = properties.Vector3('Vector corresponding to the image y-axis', default='Y') image = properties.ImagePNG('PNG image file', serializer=png_serializer, deserializer=png_deserializer)
def test_png(self): dirname, _ = os.path.split(os.path.abspath(__file__)) png_file = os.path.sep.join(dirname.split(os.path.sep) + ['temp.png']) s = ['110010010011', '101011010100', '110010110101', '100010010011'] s = [[int(v) for v in val] for val in s] f = open(png_file, 'wb') w = png.Writer(len(s[0]), len(s), greyscale=True, bitdepth=16) w.write(f, s) f.close() with self.assertRaises(TypeError): properties.ImagePNG('bad filename', filename=False) class HasPNG(properties.HasProperties): myimage = properties.ImagePNG('my image', filename='img.png') hpng = HasPNG() with self.assertRaises(ValueError): hpng.myimage = False with self.assertRaises(ValueError): hpng.myimage = properties.__file__ hpng.myimage = png_file assert isinstance(hpng.myimage, BytesIO) json_0 = properties.ImagePNG.to_json(hpng.myimage) hpng.myimage = open(png_file, 'rb') assert isinstance(hpng.myimage, BytesIO) json_1 = properties.ImagePNG.to_json(hpng.myimage) hpng.myimage = hpng.myimage assert isinstance(hpng.myimage, BytesIO) hpng.myimage = png.from_array(s, 'L;16') assert isinstance(hpng.myimage, BytesIO) json_2 = properties.ImagePNG.to_json(hpng.myimage) assert json_0 == json_1 assert json_0 == json_2 hpng.myimage = properties.ImagePNG.from_json(json_0) assert isinstance(hpng.myimage, BytesIO) with self.assertRaises(ValueError): properties.ImagePNG.from_json('pretty picture') os.remove(png_file)
class Texture2DImage(BaseTexture2D): """Contains an image that can be mapped to a 2D surface""" _resource_class = 'image' O = properties.Vector3(doc='Origin of the texture') U = properties.Vector3(doc='U axis of the texture') V = properties.Vector3(doc='V axis of the texture') image = properties.ImagePNG( doc='Image file', deserializer=image_download, ) def _nbytes(self, img=None): if img is None or (isinstance(img, string_types) and img == 'image'): img = self.image try: img.seek(0) return len(img.read()) except: raise ValueError('Texture2DImage cannot calculate the number of ' 'bytes of {}'.format(img)) @properties.validator('image') def _reject_large_files(self, change): self._validate_file_size(change['name'], change['value']) @properties.validator def _validate_image(self): self._validate_file_size('image', self.image) return True def _get_dirty_files(self, force=False): files = super(Texture2DImage, self)._get_dirty_files(force) dirty = self._dirty_props if 'image' in dirty or force: self.image.seek(0) copy = BytesIO() copy.name = 'texture_copy.png' copy.write(self.image.read()) copy.seek(0) files['image'] = FileProp(copy, 'png') return files def _get_dirty_data(self, force=False): datadict = super(Texture2DImage, self)._get_dirty_data(force) dirty = self._dirty_props if ('O' in dirty or 'U' in dirty or 'V' in dirty) or force: datadict['OUV'] = dumps( dict( O=self.O.tolist(), U=self.U.tolist(), V=self.V.tolist(), )) return datadict def _repr_png_(self): """For IPython display""" if self.image is None: return None self.image.seek(0) return self.image.read() @classmethod def _build_from_json(cls, json, **kwargs): tex = Texture2DImage(title=kwargs['title'], description=kwargs['description'], O=json['OUV']['O'], U=json['OUV']['U'], V=json['OUV']['V'], image=cls._props['image'].deserialize( json['image'])) return tex @classmethod def _build_from_omf(cls, omf_tex, omf_project): tex = Texture2DImage(title=omf_tex.name, description=omf_tex.description, O=omf_tex.origin + omf_project.origin, U=omf_tex.axis_u, V=omf_tex.axis_v, image=omf_tex.image) return tex def _to_omf(self): import omf tex = omf.ImageTexture( name=self.title or '', description=self.description or '', origin=self.O, axis_u=self.U, axis_v=self.V, image=self.image, ) return tex
class HasPNG(properties.HasProperties): myimage = properties.ImagePNG('my image', filename='img.png')