file import/export
This commit is contained in:
		
							parent
							
								
									95c1e6d9c6
								
							
						
					
					
						commit
						fbea9488f0
					
				
							
								
								
									
										80
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								README.md
									
									
									
									
									
								
							@ -12,16 +12,18 @@ Color values are specified using triplets of float values, like (128.5, 34.234,
 | 
			
		||||
 | 
			
		||||
python-FloatImg requires a shared object file (.so) that is not yet officialy available from FloatImg.
 | 
			
		||||
 | 
			
		||||
The file `floatimg/settings.py` contains the path to the .so file.
 | 
			
		||||
The file `floatimg/settings.py` contains the path to the .so file and the encoding of path characters.
 | 
			
		||||
 | 
			
		||||
## Usage
 | 
			
		||||
 | 
			
		||||
The FloatImg class encapsulate core and file functionnalities of FloatImg library. Import if from the main module:
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
import floatimg
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
The FloatImg class encapsulate core and file functionnalities of FloatImg library. Instances are created with functions from the module.
 | 
			
		||||
 | 
			
		||||
Colors are tuple of three elements `(r, g, b)`.
 | 
			
		||||
 | 
			
		||||
### Image creation
 | 
			
		||||
 | 
			
		||||
`FloatImg` has two class methods to create an image.
 | 
			
		||||
@ -47,60 +49,54 @@ new_img = img.clone()
 | 
			
		||||
new_img = img.clone(True)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### Image manipulation
 | 
			
		||||
 | 
			
		||||
#### Clear image
 | 
			
		||||
 | 
			
		||||
Reset all pixels to zero.
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
img.clear()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Copy pixels to another image
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
img.copy_data(another_img)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Set pixel value
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
img.put(x, y, (r, g, b))
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Get pixel value
 | 
			
		||||
### Basic pixel manipulation
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
# Get pixel value
 | 
			
		||||
color = (r, g, b) = img.get(x, y)
 | 
			
		||||
 | 
			
		||||
# Set pixel value
 | 
			
		||||
img.put(x, y, (r, g, b))
 | 
			
		||||
 | 
			
		||||
# Reset all pixels to zero.
 | 
			
		||||
img.clear()
 | 
			
		||||
 | 
			
		||||
# Copy pixels to another image of the same format
 | 
			
		||||
img.copy_data(another_img)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
### File manipulation
 | 
			
		||||
 | 
			
		||||
#### Dump image to file
 | 
			
		||||
#### Raw dump files
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
img.dump("/tmp/image_dump")
 | 
			
		||||
# Dump image to file
 | 
			
		||||
img.dump(path)
 | 
			
		||||
 | 
			
		||||
# Restore image data from a dump file
 | 
			
		||||
img.load(path)
 | 
			
		||||
 | 
			
		||||
# Create a new image from a dump file
 | 
			
		||||
img = floatimg.create_from_dump(path)
 | 
			
		||||
 | 
			
		||||
# Get dump metadata (TODO create a FileInfo named tuple)
 | 
			
		||||
witdh, height, img_type = floatimg.fileinfos(path)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Restore image data from a dump file
 | 
			
		||||
#### External formats
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
img.load("/tmp/image_dump")
 | 
			
		||||
# export supports the following extentions : .fimg, .png, .tiff, .pnm, .fits
 | 
			
		||||
# save as png
 | 
			
		||||
img.export("test.png")
 | 
			
		||||
 | 
			
		||||
# create an image instance from png file
 | 
			
		||||
img = floatimg.create_from_png("test.png")
 | 
			
		||||
 | 
			
		||||
# load pixel data from png file in an existing instance. size and type have to be compatible
 | 
			
		||||
img.load_png("test.png")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
#### Create a new image from a dump file
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
img = floatimg.create_from_dump("/tmp/image_dump")
 | 
			
		||||
```
 | 
			
		||||
#### Get dump metadata
 | 
			
		||||
 | 
			
		||||
TODO create a FileInfo named tuple.
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
witdh, height, img_type = floatimg.fileinfos("/tmp/image_dump")
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Operators
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ from floatimg.image import (
 | 
			
		||||
    create,
 | 
			
		||||
    create_rgb,
 | 
			
		||||
    create_from_dump,
 | 
			
		||||
    create_from_png,
 | 
			
		||||
    fileinfos,
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
import ctypes as ct
 | 
			
		||||
 | 
			
		||||
from floatimg.settings import LIB
 | 
			
		||||
from floatimg.settings import LIB, PATH_ENCODING
 | 
			
		||||
 | 
			
		||||
############################################################################################################
 | 
			
		||||
# type constants
 | 
			
		||||
@ -163,6 +163,19 @@ c_fimg_maximum.argtypes = (
 | 
			
		||||
)
 | 
			
		||||
c_fimg_maximum.restype = ct.c_int
 | 
			
		||||
 | 
			
		||||
# Files i/o
 | 
			
		||||
c_fimg_export_picture = LIB.fimg_export_picture
 | 
			
		||||
c_fimg_export_picture.argtypes = (ct.POINTER(C_FloatImg), ct.c_char_p)
 | 
			
		||||
c_fimg_export_picture.restype = ct.c_int
 | 
			
		||||
 | 
			
		||||
c_fimg_create_from_png = LIB.fimg_create_from_png
 | 
			
		||||
c_fimg_create_from_png.argtypes = (ct.c_char_p, ct.POINTER(C_FloatImg))
 | 
			
		||||
c_fimg_create_from_png.restype = ct.c_int
 | 
			
		||||
 | 
			
		||||
c_fimg_load_from_png = LIB.fimg_load_from_png
 | 
			
		||||
c_fimg_load_from_png.argtypes = (ct.c_char_p, ct.POINTER(C_FloatImg))
 | 
			
		||||
c_fimg_load_from_png.restype = ct.c_int
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
############################################################################################################
 | 
			
		||||
class FloatImg:
 | 
			
		||||
@ -175,7 +188,7 @@ class FloatImg:
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    # proxy attributes to the C_FloatImg structure
 | 
			
		||||
    # TODO: now more about them
 | 
			
		||||
    # TODO: now more about them ;)
 | 
			
		||||
    magic = property(lambda self: self.c_img.magic)
 | 
			
		||||
    fval = property(lambda self: self.c_img.fval)
 | 
			
		||||
    count = property(lambda self: self.c_img.count)
 | 
			
		||||
@ -247,22 +260,32 @@ class FloatImg:
 | 
			
		||||
        assert c_fimg_add_rgb(self.c_img_p, x, y, *color) == 0
 | 
			
		||||
 | 
			
		||||
    #######################################################################################################
 | 
			
		||||
    def dump(self, fname):
 | 
			
		||||
    def dump(self, path):
 | 
			
		||||
        """save data to a dump file"""
 | 
			
		||||
        # TODO use system encoding instead of utf-8
 | 
			
		||||
        assert (
 | 
			
		||||
            c_fimg_dump_to_file(
 | 
			
		||||
                self.c_img_p, ct.c_char_p(bytes(fname, encoding="utf8")), 0
 | 
			
		||||
                self.c_img_p, ct.c_char_p(bytes(path, encoding=PATH_ENCODING)), 0
 | 
			
		||||
            )
 | 
			
		||||
            == 0
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    #######################################################################################################
 | 
			
		||||
    def load(self, fname):
 | 
			
		||||
    def load(self, path):
 | 
			
		||||
        """load data from a dump. size and type have to be compatible"""
 | 
			
		||||
        assert (
 | 
			
		||||
            c_fimg_load_from_dump(
 | 
			
		||||
                ct.c_char_p(bytes(fname, encoding="utf8")), self.c_img_p
 | 
			
		||||
                ct.c_char_p(bytes(path, encoding=PATH_ENCODING)), self.c_img_p
 | 
			
		||||
            )
 | 
			
		||||
            == 0
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    #######################################################################################################
 | 
			
		||||
    def load_png(self, path):
 | 
			
		||||
        """load data from a png file. size and type have to be compatible"""
 | 
			
		||||
        assert (
 | 
			
		||||
            c_fimg_load_from_png(
 | 
			
		||||
                ct.c_char_p(bytes(path, encoding=PATH_ENCODING)), self.c_img_p
 | 
			
		||||
            )
 | 
			
		||||
            == 0
 | 
			
		||||
        )
 | 
			
		||||
@ -292,7 +315,7 @@ class FloatImg:
 | 
			
		||||
    def min(self, img):
 | 
			
		||||
        """return a new image with minimum pixel values per channel between current and parameter"""
 | 
			
		||||
        res = self.clone(False)
 | 
			
		||||
        # C code invert comparison
 | 
			
		||||
        # C code inverts comparison
 | 
			
		||||
        assert c_fimg_maximum(self.c_img_p, img.c_img_p, res.c_img_p) == 0
 | 
			
		||||
        return res
 | 
			
		||||
 | 
			
		||||
@ -300,12 +323,19 @@ class FloatImg:
 | 
			
		||||
    def max(self, img):
 | 
			
		||||
        """return a new image with maximum pixel values per channel between current and parameter"""
 | 
			
		||||
        res = self.clone(False)
 | 
			
		||||
        # C code invert comparison
 | 
			
		||||
        # C code inverts comparison
 | 
			
		||||
        assert c_fimg_minimum(self.c_img_p, img.c_img_p, res.c_img_p) == 0
 | 
			
		||||
        return res
 | 
			
		||||
 | 
			
		||||
    # TODO
 | 
			
		||||
    # export(fname, flags) : depending file extension, save to the correct format
 | 
			
		||||
    #######################################################################################################
 | 
			
		||||
    def export(self, path):
 | 
			
		||||
        """export image to path. allowed extension: .fimg, .png, .tiff, .pnm, .fits"""
 | 
			
		||||
        assert (
 | 
			
		||||
            c_fimg_export_picture(
 | 
			
		||||
                self.c_img_p, ct.c_char_p(bytes(path, encoding=PATH_ENCODING)), 0
 | 
			
		||||
            )
 | 
			
		||||
            == 0
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###########################################################################################################
 | 
			
		||||
@ -313,7 +343,9 @@ def fileinfos(fname):
 | 
			
		||||
    """return witdh, height, img_type triplet read from a dump file"""
 | 
			
		||||
    datas = (ct.c_int * 3)()
 | 
			
		||||
    assert (
 | 
			
		||||
        c_fimg_fileinfos(ct.c_char_p(bytes(fname, encoding="utf8")), ct.pointer(datas))
 | 
			
		||||
        c_fimg_fileinfos(
 | 
			
		||||
            ct.c_char_p(bytes(fname, encoding=PATH_ENCODING)), ct.pointer(datas)
 | 
			
		||||
        )
 | 
			
		||||
        == 0
 | 
			
		||||
    )
 | 
			
		||||
    return datas[:3]
 | 
			
		||||
@ -335,14 +367,25 @@ def create_rgb(witdh, height):
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###########################################################################################################
 | 
			
		||||
def create_from_dump(fname):
 | 
			
		||||
    """Create a new instance from a dump file"""
 | 
			
		||||
    witdh, height, img_type = fileinfos(fname)
 | 
			
		||||
def create_from_dump(path):
 | 
			
		||||
    """Create a FloatImg instance from a dump file"""
 | 
			
		||||
    witdh, height, img_type = fileinfos(path)
 | 
			
		||||
    img = create(witdh, height, img_type)
 | 
			
		||||
    img.load(fname)
 | 
			
		||||
    img.load(path)
 | 
			
		||||
    return img
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###########################################################################################################
 | 
			
		||||
def create_from_png(path):
 | 
			
		||||
    """Create a FloatImg instance from a png file"""
 | 
			
		||||
    img = C_FloatImg()
 | 
			
		||||
    assert (
 | 
			
		||||
        c_fimg_create_from_png(ct.c_char_p(bytes(path, encoding=PATH_ENCODING)), img)
 | 
			
		||||
        == 0
 | 
			
		||||
    )
 | 
			
		||||
    return FloatImg(img)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
###########################################################################################################
 | 
			
		||||
def type_is_valid(type_id):
 | 
			
		||||
    """return True if type_id is a valid one"""
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
import ctypes
 | 
			
		||||
 | 
			
		||||
# LIB = ctypes.cdll.LoadLibrary("../FloatImg/libfloatimg.so")
 | 
			
		||||
PATH_ENCODING = "utf8"
 | 
			
		||||
 | 
			
		||||
LIB = ctypes.cdll.LoadLibrary("../FloatImg4PythonBinding/build/lib/libfloatimg.so")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										28
									
								
								tests/files.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								tests/files.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,28 @@
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
import floatimg
 | 
			
		||||
 | 
			
		||||
def create_img():
 | 
			
		||||
    width, height = 5, 5
 | 
			
		||||
    img = floatimg.create_rgb(width, height)
 | 
			
		||||
    img.fill((255.0, 0.0, 0.0))
 | 
			
		||||
    return img
 | 
			
		||||
 | 
			
		||||
def test_png():
 | 
			
		||||
    width, height = 5, 5
 | 
			
		||||
    path = "test.png"
 | 
			
		||||
    img = create_img()
 | 
			
		||||
    img.export(path)
 | 
			
		||||
    assert os.path.getsize(path) == 74
 | 
			
		||||
    img2 = floatimg.create_from_png(path)
 | 
			
		||||
    for y in range(height):
 | 
			
		||||
        for x in range(width):
 | 
			
		||||
            assert img.get(x, y) == img2.get(x, y)
 | 
			
		||||
 | 
			
		||||
    img3 = img2.clone(False)
 | 
			
		||||
    img3.load_png(path)
 | 
			
		||||
    for y in range(height):
 | 
			
		||||
        for x in range(width):
 | 
			
		||||
            assert img.get(x, y) == img3.get(x, y)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user