PyLibTiff - a wrapper to the libtiff library to Python using ctypes

Overview

Build Status

Build status

PyLibTiff is a package that provides:

  • a wrapper to the libtiff library to Python using ctypes.

  • a pure Python module for reading and writing TIFF and LSM files. The images are read as numpy.memmap objects so that it is possible to open images that otherwise would not fit to computers RAM. Both TIFF strips and tiles are supported for low-level data storage.

There exists many Python packages such as PIL, FreeImagePy that support reading and writing TIFF files. The PyLibTiff project was started to have an efficient and direct way to read and write TIFF files using the libtiff library without the need to install any unnecessary packages or libraries. The pure Python module was created for reading "broken" TIFF files such as LSM files that in some places use different interpretation of TIFF tags than what specified in the TIFF specification document. The libtiff library would just fail reading such files. In addition, the pure Python module is more memory efficient as the arrays are returned as memory maps. Support for compressed files is not implemented yet.

tifffile.py by Christoph Gohlke is an excellent module for reading TIFF as well as LSM files, it is as fast as libtiff.py by using numpy.

Usage example (libtiff wrapper)

>>> from libtiff import TIFF
>>> # to open a tiff file for reading:
>>> tif = TIFF.open('filename.tif', mode='r')
>>> # to read an image in the currect TIFF directory and return it as numpy array:
>>> image = tif.read_image()
>>> # to read all images in a TIFF file:
>>> for image in tif.iter_images(): # do stuff with image
>>> # to open a tiff file for writing:
>>> tif = TIFF.open('filename.tif', mode='w')
>>> # to write a image to tiff file
>>> tif.write_image(image)

Usage example (pure Python module)

>>> from libtiff import TIFFfile, TIFFimage
>>> # to open a tiff file for reading
>>> tif = TIFFfile('filename.tif')
>>> # to return memmaps of images and sample names (eg channel names, SamplesPerPixel>=1)
>>> samples, sample_names = tiff.get_samples()
>>> # to create a tiff structure from image data
>>> tiff = TIFFimage(data, description='')
>>> # to write tiff structure to file
>>> tiff.write_file('filename.tif', compression='none') # or 'lzw'
>>> del tiff # flushes data to disk

Script usage examples

$ libtiff.info -i result_0.tif --no-gui
IFDEntry(tag=ImageWidth, value=512, count=1, offset=None)
IFDEntry(tag=ImageLength, value=512, count=1, offset=None)
IFDEntry(tag=BitsPerSample, value=32, count=1, offset=None)
IFDEntry(tag=Compression, value=1, count=1, offset=None)
IFDEntry(tag=PhotometricInterpretation, value=1, count=1, offset=None)
IFDEntry(tag=StripOffsets, value=8, count=1, offset=None)
IFDEntry(tag=Orientation, value=6, count=1, offset=None)
IFDEntry(tag=StripByteCounts, value=1048576, count=1, offset=None)
IFDEntry(tag=PlanarConfiguration, value=1, count=1, offset=None)
IFDEntry(tag=SampleFormat, value=3, count=1, offset=None)
Use --ifd to see the rest of 31 IFD entries
data is contiguous: False
memory usage is ok: True
sample data shapes and names:

width : 512
length : 512
samples_per_pixel : 1
planar_config : 1
bits_per_sample : 32
strip_length : 1048576

[('memmap', (32, 512, 512), dtype('float32'))] ['sample0']
$ libtiff.info --no-gui -i psf_1024_z5_airy1_set1.lsm
IFDEntry(tag=NewSubfileType, value=0, count=1, offset=None)
IFDEntry(tag=ImageWidth, value=1024, count=1, offset=None)
IFDEntry(tag=ImageLength, value=1024, count=1, offset=None)
IFDEntry(tag=BitsPerSample, value=8, count=1, offset=None)
IFDEntry(tag=Compression, value=1, count=1, offset=None)
IFDEntry(tag=PhotometricInterpretation, value=1, count=1, offset=None)
IFDEntry(tag=StripOffsets, value=97770, count=1, offset=None)
IFDEntry(tag=SamplesPerPixel, value=1, count=1, offset=None)
IFDEntry(tag=StripByteCounts, value=1048576, count=1, offset=None)
IFDEntry(tag=PlanarConfiguration, value=2, count=1, offset=None)
IFDEntry(tag=CZ_LSMInfo, value=CZ_LSMInfo276(
  MagicNumber=[67127628], 
  StructureSize=[500], 
  DimensionX=[1024], 
  DimensionY=[1024], 
  DimensionZ=[20], 
  DimensionChannels=[1], 
  DimensionTime=[1], 
  SDataType=[1], 
  ThumbnailX=[128], 
  ThumbnailY=[128], 
  VoxelSizeX=[  2.79017865e-08], 
  VoxelSizeY=[  2.79017865e-08], 
  VoxelSizeZ=[  3.60105263e-07], 
  OriginX=[ -2.22222228e-07], 
  OriginY=[  1.90476196e-07], 
  OriginZ=[ 0.], 
  ScanType=[0], 
  SpectralScan=[0], 
  DataType=[0], 
  OffsetVectorOverlay->DrawingElement(name='OffsetVectorOverlay', size=200, offset=6560), 
  OffsetInputLut->LookupTable(name='OffsetInputLut', size=8388, subblocks=6, channels=1, offset=7560), 
  OffsetOutputLut->LookupTable(name='OffsetOutputLut', size=24836, subblocks=3, channels=3, offset=15948), 
  OffsetChannelColors->ChannelColors (names=['Ch3'], colors=[(255, 0, 0, 0)]), 
  TimeInterval=[ 0.], 
  OffsetChannelDataTypes->None, 
  OffsetScanInformation->recording[size=3535]
   name = 'psf_1024_z5_airy1_set1'
   description = ' '
   notes = ' '
   objective = 'C-Apochromat 63x/1.20 W Korr UV-VIS-IR M27'
   special scan mode = 'FocusStep'
   scan type = ''
   scan mode = 'Stack'
   number of stacks = 10
   lines per plane = 1024
   samples per line = 1024
   planes per volume = 20
   images width = 1024
   images height = 1024
   images number planes = 20
   images number stacks = 1
   images number channels = 1
   linescan xy size = 512
   scan direction = 0
   scan directionz = 0
   time series = 0
   original scan data = 1
   zoom x = 5.0000000000000009
   zoom y = 5.0000000000000009
   zoom z = 1.0
   sample 0x = -0.22200000000000006
   sample 0y = 0.19000000000000006
   sample 0z = 6.8420000000000014
   sample spacing = 0.028000000000000008
   line spacing = 0.028000000000000008
   plane spacing = 0.3600000000000001
   rotation = 0.0
   nutation = 0.0
   precession = 0.0
   sample 0time = 39583.598368055624
   start scan trigger in = ''
   start scan trigger out = ''
   start scan event = 0
   start scan time = 0.0
   stop scan trigger in = ''
   stop scan trigger out = ''
   stop scan event = 0
   start scan time = 0.0
   use rois = 0
   use reduced memory rois = 0
   user = 'User Name'
   usebccorrection = 0
   positionbccorrection1 = 0.0
   positionbccorrection2 = 0.0
   interpolationy = 1
   camera binning = 1
   camera supersampling = 0
   camera frame width = 1388
   camera frame height = 1040
   camera offsetx = 0.0
   camera offsety = 0.0
   rt binning = 1
  ENTRY0x10000064L = 1
   rt frame width = 512
   rt frame height = 512
   rt region width = 512
   rt region height = 512
   rt offsetx = 0.0
   rt offsety = 0.0
   rt zoom = 1.0000000000000004
   rt lineperiod = 112.43300000000002
   prescan = 0
  lasers[size=188]
    laser[size=80]
       name = 'HeNe633'
       acquire = 1
       power = 5.0000000000000009
    end laser
    laser[size=84]
       name = 'DPSS 532-75'
       acquire = 1
       power = 75.000000000000014
    end laser
  end lasers
  tracks[size=2071]
    track[size=2047]
       pixel time = 1.5980000000000003
       time between stacks = 1.0
       multiplex type = 1
       multiplex order = 1
       sampling mode = 2
       sampling method = 1
       sampling number = 8
       acquire = 1
       name = 'Track'
       collimator1 position = 16
       collimator1 name = 'IR/Vis'
       collimator2 position = 66
       collimator2 name = 'UV/Vis'
       is bleach track = 0
       is bleach after scan number = 0
       bleach scan number = 0
       trigger in = ''
       trigger out = ''
       is ratio track = 0
       bleach count = 0
       spi center wavelength = 582.53000000000009
       id condensor aperture = 'KAB1'
       condensor aperture = 0.55000000000000016
       id condensor revolver = 'FW2'
       condensor filter = 'HF'
       id tubelens = 'Tubelens'
       id tubelens position = 'Lens LSM'
       transmitted light = 0.0
       reflected light = -1.0000000000000002
      detection channels[size=695]
        detection channel[size=671]
           detector gain first = 700.00000000000011
           detector gain last = 700.00000000000011
           amplifier gain first = 1.0000000000000002
           amplifier gain last = 1.0000000000000002
           amplifier offs first = 0.10000000000000002
           amplifier offs last = 0.10000000000000002
           pinhole diameter = 144.00000000000003
           counting trigger = 5.0
           acquire = 1
           integration mode = 0
           special mode = 0
           detector name = 'Pmt3'
           amplifier name = 'Amplifier1'
           pinhole name = 'PH3'
           filter set name = 'EF3'
           filter name = 'LP 650'
          ENTRY0x70000011L = ''
          ENTRY0x70000012L = ''
           integrator name = 'Integrator3'
           detection channel name = 'Ch3'
           detector gain bc1 = 0.0
           detector gain bc2 = 0.0
           amplifier gain bc1 = 0.0
           amplifier gain bc2 = 0.0
           amplifier offs bc1 = 0.0
           amplifier offs bc2 = 0.0
           spectral scan channels = 32
           spi wavelength start = 415.0
           spi wavelength end = 735.0
          ENTRY0x70000024L = 575.0
          ENTRY0x70000025L = 575.0
           dye name = ''
           dye folder = ''
          ENTRY0x70000028L = 1.0000000000000004
          ENTRY0x70000029L = 0.0
        end detection channel
      end detection channels
      beam splitters[size=330]
        beam splitter[size=82]
           filter set = 'HT'
           filter = 'HFT 405/514/633'
           name = 'HT'
        end beam splitter
        beam splitter[size=75]
           filter set = 'NT1'
           filter = 'Mirror'
           name = 'NT1'
        end beam splitter
        beam splitter[size=76]
           filter set = 'NT2'
           filter = 'NFT 565'
           name = 'NT2'
        end beam splitter
        beam splitter[size=73]
           filter set = 'FW1'
           filter = 'None'
           name = 'FW1'
        end beam splitter
      end beam splitters
      illumination channels[size=160]
        illumination channel[size=136]
           name = '633'
           power = 0.30000000000000004
           wavelength = 633.0
           aquire = 1
           power bc1 = 0.0
           power bc2 = 0.0
        end illumination channel
      end illumination channels
      data channels[size=338]
        data channel[size=314]
           name = 'Ch3'
           acquire = 1
           acquire = 0
           color = 255
           sampletype = 1
           bitspersample = 8
           ratio type = 0
           ratio track1 = 0
           ratio track2 = 0
           ratio channel1 = ''
           ratio channel2 = ''
           ratio const1 = 0.0
           ratio const2 = 0.0
           ratio const3 = 1.0
           ratio const4 = 0.0
           ratio const5 = 0.0
           ratio const6 = 0.0
        end data channel
      end data channels
    end track
  end tracks
  timers[size=24]
  end timers
  markers[size=24]
  end markers
end recording, 
  OffsetKsData->OffsetData(name='OffsetKsData', size=8, offset=48590), 
  OffsetTimeStamps->TimeStamps(stamps=[ 2335.75582836]), 
  OffsetEventList->EventList(events=[]), 
  OffsetRoi->DrawingElement(name='OffsetRoi', size=200, offset=6160), 
  OffsetBleachRoi->DrawingElement(name='OffsetBleachRoi', size=200, offset=6360), 
  OffsetNextRecording->None, 
  DisplayAspectX=[ 1.], 
  DisplayAspectY=[ 1.], 
  DisplayAspectZ=[ 1.], 
  DisplayAspectTime=[ 1.], 
  OffsetMeanOfRoisOverlay->DrawingElement(name='OffsetMeanOfRoisOverlay', size=200, offset=6760), 
  OffsetTopoIsolineOverlay->DrawingElement(name='OffsetTopoIsolineOverlay', size=200, offset=7160), 
  OffsetTopoProfileOverlay->DrawingElement(name='OffsetTopoProfileOverlay', size=200, offset=7360), 
  OffsetLinescanOverlay->DrawingElement(name='OffsetLinescanOverlay', size=200, offset=6960), 
  ToolbarFlags=[0], 
  OffsetChannelWavelength->ChannelWavelength (ranges=[(-1.0, -1.0)]), 
  OffsetChannelFactors->ChannelFactors(size=36, offset=40836), 
  ObjectiveSphereCorrection=[ 0.], 
  OffsetUnmixParameters->OffsetData(name='OffsetUnmixParameters', size=124, offset=48466), 
  Reserved=[[40896 44726     0     0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0]]))
Use --ifd to see the rest of 39 IFD entries
data is contiguous: False
memory usage is ok: True
sample data shapes and names:

width : 1024
length : 1024
samples_per_pixel : 1
planar_config : 2
bits_per_sample : 8
strip_length : 1048576

[('memmap', (20, 1024, 1024), dtype('uint8'))] ['Ch3']
[((20, 128, 128), dtype('uint8')), ((20, 128, 128), dtype('uint8')), ((20, 128, 128), dtype('uint8'))] ['red', 'green', 'blue']
Comments
  • Fail to import libtiff in Ubuntu 14.04

    Fail to import libtiff in Ubuntu 14.04

    What steps will reproduce the problem?
    1.import libtiff
    
    
    What is the expected output? What do you see instead?
    Failed to find TIFF header file (may be need to run: sudo apt-get install 
    libtiff4-dev)
    
    What version of the product are you using? On what operating system?
    Ubuntu 14.04
    
    Please provide any additional information below.
    Ubuntu 14.04 come with libtiff5 by default, replace it with libtiff4 seems not 
    a simple task since several hundreds of package depends on libtiff5.
    
    

    Original issue reported on code.google.com by [email protected] on 10 Sep 2014 at 8:50

    Priority-Medium Type-Defect auto-migrated 
    opened by GoogleCodeExporter 14
  • error in importing libtiff

    error in importing libtiff

    I am trying to use pylibtiff to read tiff files into numpy array.. i installed 
    the windows installer provided on the site and now if i try importing, python 
    encounters with following error:
    
    >>> from libtiff import *
    
    Traceback (most recent call last):
      File "D:/Python27/testtifflib.py", line 4, in <module>
        from libtiff import *
      File "D:\Python27\lib\site-packages\libtiff\__init__.py", line 4, in <module>
        from .libtiff import libtiff, TIFF
      File "D:\Python27\lib\site-packages\libtiff\libtiff.py", line 35, in <module>
        raise ImportError('Failed to find TIFF library. Make sure that libtiff is installed and its location is listed in PATH|LD_LIBRARY_PATH|..')
    ImportError: Failed to find TIFF library. Make sure that libtiff is installed 
    and its location is listed in PATH|LD_LIBRARY_PATH|..
    
    i also tried this :
    
    import sys
    sys.path.append("D:\\Python27\\Lib\\site-packages\\libtiff")
    
    from libtiff import *
    
    but same error persists.. what can be done in this case??  any help is 
    appreciated.. m i missing something here??
    
    
    

    Original issue reported on code.google.com by [email protected] on 2 Feb 2011 at 12:35

    Priority-Medium Type-Defect auto-migrated 
    opened by GoogleCodeExporter 11
  • installing through pip fails in python 3

    installing through pip fails in python 3

    > pip install libtiff
    Collecting libtiff
      Downloading libtiff-0.4.0.tar.gz (119kB)
        100% |████████████████████████████████| 122kB 2.9MB/s
        Complete output from command python setup.py egg_info:
        Warning: Assuming default configuration (libtiff/bitarray-0.3.5-numpy/bitarray/{setup_bitarray,setup}.py was not found)Traceback (most recent call last):
          File "<string>", line 1, in <module>
          File "/private/var/folders/tv/0sj3cm251x14b29kb6xzs27r0000gn/T/pip-build-nwvzm3eq/libtiff/setup.py", line 96, in <module>
            configuration = configuration,
          File "/Users/waspinator/anaconda/lib/python3.5/site-packages/numpy/distutils/core.py", line 135, in setup
            config = configuration()
          File "/private/var/folders/tv/0sj3cm251x14b29kb6xzs27r0000gn/T/pip-build-nwvzm3eq/libtiff/setup.py", line 67, in configuration
            config.get_version('libtiff/version.py')
          File "/Users/waspinator/anaconda/lib/python3.5/site-packages/numpy/distutils/misc_util.py", line 1917, in get_version
            fn, info)
          File "/Users/waspinator/anaconda/lib/python3.5/site-packages/numpy/compat/py3k.py", line 112, in npy_load_module
            return importlib.machinery.SourceFileLoader(name, fn).load_module()
          File "<frozen importlib._bootstrap_external>", line 388, in _check_name_wrapper
          File "<frozen importlib._bootstrap_external>", line 809, in load_module
          File "<frozen importlib._bootstrap_external>", line 668, in load_module
          File "<frozen importlib._bootstrap>", line 268, in _load_module_shim
          File "<frozen importlib._bootstrap>", line 693, in _load
          File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
          File "<frozen importlib._bootstrap_external>", line 661, in exec_module
          File "<frozen importlib._bootstrap_external>", line 767, in get_code
          File "<frozen importlib._bootstrap_external>", line 727, in source_to_code
          File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
          File "libtiff/version.py", line 30
            print version
                        ^
        SyntaxError: Missing parentheses in call to 'print'
        Appending libtiff.bitarray configuration to libtiff
        Ignoring attempt to set 'name' (from 'libtiff' to 'libtiff.bitarray')
        Appending libtiff configuration to
        Ignoring attempt to set 'name' (from '' to 'libtiff')
    
    opened by waspinator 10
  • Ignore deprecation defines added in tiff 4.3 headers.

    Ignore deprecation defines added in tiff 4.3 headers.

    Without this fix the following error occurs:

    ('__attribute__((deprecated))', '#define TIFF_GCC_DEPRECATED __attribute__((deprecated))\n') name '__attribute__' is not defined
    Traceback (most recent call last):
      File "/home/bob/git/pylibtiff/./test.py", line 3, in <module>
        import libtiff
      File "/home/bob/git/pylibtiff/libtiff/__init__.py", line 23, in <module>
        from .libtiff_ctypes import libtiff, TIFF, TIFF3D  # noqa: F401
      File "/home/bob/git/pylibtiff/libtiff/libtiff_ctypes.py", line 127, in <module>
        value = eval(value)
      File "<string>", line 1, in <module>
    NameError: name '__attribute__' is not defined
    
    opened by robert-ancell 9
  • tests fail on all os.remove() on Windows

    tests fail on all os.remove() on Windows

    Temporary files are locked on Windows, so they can not be removed without 
    closing beforehand.
    
    Log file of nosetests on Windows 7, VS2008, Python 2.7 attached. 
    
    I tried to fix the error by calling .close() method on objects that opened the 
    files, deleting mmaped variables and/or TIFFfile or TIFFimage instances before 
    calling os.remove(). It didn't solve the issue unfortunately. The mmaped numpy 
    arrays are somehow still open.
    

    Original issue reported on code.google.com by [email protected] on 8 Nov 2011 at 9:06

    Attachments:

    Priority-Medium Type-Defect auto-migrated 
    opened by GoogleCodeExporter 9
  • Does work for 1bit compressed TIFF

    Does work for 1bit compressed TIFF

    It seems that the library is working well for greyscale and color images, but 
    as soon as a pure black&white (1bit/1plan) is given, it fails and renders a 
    totally black image
    
    I suppose there is something to do in read_image function cause I saw some 
    comments in the code saying "TODO: check for correctness"
    
    
    
    
    

    Original issue reported on code.google.com by [email protected] on 11 Mar 2011 at 4:07

    Priority-Medium Type-Defect auto-migrated 
    opened by GoogleCodeExporter 9
  • Segmentation fault at

    Segmentation fault at "from libtiff import TIFF" / dlopen(...tif_lzw.so") with python 2.6

    What steps will reproduce the problem?
    1. run enthought python distribution 6.3-2 on scientific linux 5
    2. build/install pylibtiff (revision 70)
    3. run python -c "from libtiff import TIFF"
    
    What is the expected output? What do you see instead?
    $ python -v -d -c "from libtiff import TIFF"
    ....
    
    import copy # precompiled from /scratch/epd-6.3-2-rh5-x86/lib/python2.6/copy.pyc
    # /scratch/pylibtiff.i386/lib/python/libtiff/tiff_base.pyc matches 
    /scratch/pylibtiff.i386/lib/python/libtiff/tiff_base.py
    import libtiff.tiff_base # precompiled from 
    /scratch/pylibtiff.i386/lib/python/libtiff/tiff_base.pyc
    # /scratch/pylibtiff.i386/lib/python/libtiff/lsm.pyc matches 
    /scratch/pylibtiff.i386/lib/python/libtiff/lsm.py
    import libtiff.lsm # precompiled from 
    /scratch/pylibtiff.i386/lib/python/libtiff/lsm.pyc
    dlopen("/scratch/pylibtiff.i386/lib/python/libtiff/tif_lzw.so", 102);
    Segmentation fault
    
    
    
    What version of the product are you using? On what operating system?
    
    $ python -V
    Python 2.6.6 -- EPD 6.3-2 (32-bit)
    
    $ uname -a
    Linux pc6490 2.6.18-194.26.1.el5 #1 SMP Tue Nov 9 12:56:26 EST 2010 i686 i686 
    i386 GNU/Linux
    
    
    Please provide any additional information below.
    
    Works o.k. with python 2.7. 
    
    
    

    Original issue reported on code.google.com by [email protected] on 19 Jan 2011 at 2:17

    Priority-Medium Type-Defect auto-migrated 
    opened by GoogleCodeExporter 9
  • Bundled bitarray appears to not be Python 3.11 compatible

    Bundled bitarray appears to not be Python 3.11 compatible

    The conda-forge community has started building packages for Python 3.11. It seems that pylibtiff is having trouble building under Python 3.11 with errors like:

      libtiff/bitarray-a1646c0/bitarray/_bitarray.c:148:23: error: lvalue required as left operand of assignment
        148 |         Py_SIZE(self) = newsize;
            |                       ^
      libtiff/bitarray-a1646c0/bitarray/_bitarray.c:175:19: error: lvalue required as left operand of assignment
        175 |     Py_SIZE(self) = newsize;
            |                   ^
      libtiff/bitarray-a1646c0/bitarray/_bitarray.c: In function 'newbitarrayobject':
      libtiff/bitarray-a1646c0/bitarray/_bitarray.c:196:18: error: lvalue required as left operand of assignment
        196 |     Py_SIZE(obj) = nbytes;
            |                  ^
    

    I'm guessing this is due to how old the bundled bitarray is in pylibtiff. Any chance of updating it and making a new release?

    Here is the conda-forge PR for Python 3.11: https://github.com/conda-forge/pylibtiff-feedstock/pull/14

    bug 
    opened by djhoese 8
  • Looking for maintainers?

    Looking for maintainers?

    @pearu What's your availability for this project? It looks like I still have some minimal permissions based on my old participation in the project, but I'm wondering if you're open to more maintainers or increasing my level of permissions to fix some of the "modernization" issues (#134, #133, etc). I also have some others in the Pytroll community (maintainers of satpy, pyresample) who use this library and would be willing to help review things when they can.

    What are your thoughts?

    If anyone else is willing to help maintain this library feel free to comment.

    Edit: Looks like I have permission to merge pull requests so I guess I don't need to ask, but I'm not familiar with the current release process and want to respect any current practices of the project.

    help wanted question code quality 
    opened by djhoese 7
  • TIFF wrapper compatibility broken due to all function names being lowercase.

    TIFF wrapper compatibility broken due to all function names being lowercase.

    The latest git HEAD, since commit bdce54fb, has broken compatibility with all our code. All the methods of the TIFF class have been renamed to only be lowercase.

    So simple code like this is broken:

        f = TIFF.open(fn, mode='r')
        if f.IsTiled():
            bits = f.GetField('BitsPerSample')
            sample_format = f.GetField('SampleFormat')
            typ = f.get_numpy_type(bits, sample_format)
            im = f.read_tiles(typ)
        else:
            im = f.read_image() # Fist image
    

    Now, both .IsTiled() and .GetField() don't exist, as they've been renamed to .istiled() and getfield(). Note that the Python convention is to either have CamelCase, or lower_case names, however, it is not recommended to use lowercase without separation (because it makes names hard to read).

    IMHO, in this case, as it's wrapper doing a simple mapping of C functions to Python methods, it makes sense to use the same convention as the C library, so that it's more obvious that they are just direct mapping. For the more complex methods, like read_image(), it's also fine to follow a different convention, as they are not a direct mapping of the C library, but additional helper code.

    So, I'd suggest to revert the renaming of the methods. If needed, I can provide a patch.

    opened by pieleric 7
  • Renaming `pylibtiff` to `libtiff` causes issues for some build systems

    Renaming `pylibtiff` to `libtiff` causes issues for some build systems

    As some build systems (e.g. conda and Linux package managers) can install libtiff when referring to the actual library. Renaming of this package from libtiff to pylibtiff can cause them some confusion. Would it be too much to ask that the package be renamed to pylibtiff?

    opened by jakirkham 7
  • Possible to specify RGB and YCbCr colorspaces?

    Possible to specify RGB and YCbCr colorspaces?

    JPEG format allows storing pixel values in RGB and YCbCr colorspaces. In addition to that, with YCbCr it is possible to enable Chromaticity subsampling which in most cases improves the compression.

    Does your package provide the possibility to explicitly specify TiffTag 530 YCbCrSubSampling and TiffTag 262 PhotometricInterpretation?

    What would an example of saving a TIFF file with these parameters look like?

    opened by ilykos 0
  • Proposed updates to CI testing and release creation

    Proposed updates to CI testing and release creation

    After talking with @pearu in #136, he said that updating testing and releasing of pylibtiff would be appreciated. Here's what I propose towards that end with some of the gotchas someone unfamiliar with these steps should maybe be aware of. Note none of this is new to me and I have multiple projects doing at least a couple of these things.

    1. Package versioning: Use setuptools-scm (https://pypi.org/project/setuptools-scm/) for automatic package versioning based on git tags. You may have also heard of versioneer which is another package that provides similar functionality (but I prefer setuptools-scm). This essentially removes any manual version editing in setup.py. The one downside is you may get some users who don't install the package before trying to use it from source. This will error as the version number for the package isn't generated until you pip install -e . (to make an editable/developer install) or do pip install . to do an in-environment full install. Otherwise, once properly configured, this simplifies so much.
    2. Remove Python 2.7 support.
    3. Remove travis and appveyor CI
    4. Add github action CI
    5. Add building of wheels for major platforms to github action CI (I assume this doesn't require libtiff to be installed)
    6. Add deployment of sdist and wheels to github actions when a GitHub release is made. This will require @pearu (who is the only PyPI pylibtiff maintainer) to make an access token on PyPI and save it as a secret in this github repository (see "Settings" on this repository).
    7. Update release instructions to reflect the new procedure (git tag, push, make github release, done).

    Optional long term changes:

    1. Remove numpy Configuration usage. I have no idea how this stuff works and it really feels like it obfuscates the whole building process. Especially since there are two of them.
    2. Use a changelog generator to make a CHANGELOG.md for every release which will automatically pull from github closed issues and pull requests and format things nicely for user/reader ingest.
    3. Drop the extra setup.py command line flags/options/commands. Are they used on a regular basis besides the releasing process?
    4. Eventually try moving to only a pyproject.toml and remove the setup.py.
    5. A pre-commit with black auto-formatter and lint checking.
    code quality 
    opened by djhoese 5
  • Tiled multi-page tiff corrupted?

    Tiled multi-page tiff corrupted?

    Hello, thanks for this interesting package. After installing it using pip install git+https://github.com/pearu/pylibtiff in macOS Catilina 10.15.7 (Python 3.8.3 [Clang 10.0.0 ] :: Anaconda, Inc. on darwin) using this test data:

    import skimage
    import matplotlib.pyplot as plt
    import numpy as np
    test = skimage.data.astronaut()
    plt.imshow(test)
    
    # we dstack many test images togheter to create our test data
    data = skimage.data.astronaut()
    for i in range(4):
        data = np.dstack([data,data])
    

    I have tried to generate a tiled multi-page tif

    from libtiff import TIFF
    imagename = "libtiff_astro.tif"
    # to open a tiff file for writing:
    tif = TIFF.open("/Users/univr/Documents/iipsrv/images/%s"%imagename, mode='w')
    # to write a image to tiff file
    tif.write_tiles(data,tile_width=256,tile_height=256,compression=None,write_rgb=None)
    

    However, this results in a corrupted file. Can you please give me some hints on how to solve it? Thanks a lot. Giacomo

    opened by giacomomarchioro 0
  • Adding Power support(ppc64le) with continuous integration/testing to the project for architecture independent

    Adding Power support(ppc64le) with continuous integration/testing to the project for architecture independent

    I am part of IBM team and working on porting power arch to packages as continuous integration & testing.

    This is part of the Ubuntu distribution for ppc64le. This helps us simplify testing later when distributions are re-building and re-releasing,We typically build applications for customers and ISVs, and while we don't use this package directly, we do count on all of the packages in debian/ubuntu to build other packages. So we more likely have this as a second or third level dependency and couldn't tell you explicitly which features we use or our usage model,For more info tag @gerrith3.

    Pls verify and merge

    opened by asellappen 1
  • Add debug logging which libtiff.dll is actually used

    Add debug logging which libtiff.dll is actually used

    To avoid conflicts with user-defined libtiffs (especially those named libtiff3.dll, see #123 and #124 ) we have patched the libtiff.dll to always print its loaded libtiff.dll location + version.

    If I find the time, I will make a pull request to show what we mean.

    opened by JoostvanPinxten 0
  • Clean up loading of libtiff.dll's

    Clean up loading of libtiff.dll's

    Why is the loading of libtiff.dll's giving priority to a libtiff3.dll?

    To me it would make more sense to try to load a libtiff.dll first (which is the default name for a version 4+ libtiff nowadays).

    opened by JoostvanPinxten 2
Releases(v0.5.1)
  • v0.5.1(Dec 29, 2022)

    • Fix "scripts" sub-package
    • Various ctypes fixes
    • Add TIFF_HEADER_PATH to force header location
    • Fix handling of line continuations with libtiff 4.5.0
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0.post0(Dec 13, 2022)

  • v0.5.0(Dec 13, 2022)

    • Major package structure and CI overhaul
    • libtiff.info and libtiff.convert scripts are now setuptools entry points (console_scripts). Functionally the same, but code is executed differently.
    • Remove unused bundled bitarray
    • Fix numpy np.bool usage
    Source code(tar.gz)
    Source code(zip)
  • v0.4.4(Oct 3, 2021)

Owner
Pearu Peterson
Pearu Peterson
This piece of code is a User Welcomer with Image Manipulation using Python and Pillow (PIL).

This piece of code is a User Welcomer with Image Manipulation using Python and Pillow (PIL).

Bero 4 Jan 11, 2022
将位图转为彩色矢量 svg 图片

一个将位图描摹为彩色矢量 svg 图片的程序,是一个命令行工具,使用 Python 脚本实现,运行环境 Python3.8+。 ✨ 效果 以一个字帖图片为例,这是 png 格式的位图(370KB): 这是颜

Haujet Zhao 104 Dec 30, 2022
An agnostic Canvas API for the browser-less and insane

Apollo An agnostic Canvas API for the browser-less and mildly insane. Project Apollo is a Pythonic re-imagining of HTML Canvas element implementati

1 Jan 13, 2022
A quick and dirty QT Statusbar implementation for grabbing GIFs from Tenor, since there is no offical or unofficial one I found. This was intended for use under Linux, however it was also functional enough on MacOS.

Statusbar-TenorGIF App for Linux A quick and dirty QT Statusbar implementation for grabbing GIFs from Tenor, since there is no offical one and I didnt

Luigi DaVinci 1 Nov 01, 2021
Simple program to easily view Euler parameters in 3D.

Simple program to easily view Euler parameters in 3D.

5 Aug 20, 2021
OctoPrint is the snappy web interface for your 3D printer!

OctoPrint OctoPrint provides a snappy web interface for controlling consumer 3D printers. It is Free Software and released under the GNU Affero Genera

OctoPrint 7.1k Jan 03, 2023
LSB Image Steganography Using Python

Steganography is the science that involves communicating secret data in an appropriate multimedia carrier, e.g., image, audio, and video files

Mahmut Can Gönül 2 Nov 04, 2021
Generate waves art for an image

waves-art Generate waves art for an image. Requirements: OpenCV Numpy Example Usage python waves_art.py --image_path tests/test1.jpg --patch_size 15 T

Hamza Rawal 18 Apr 04, 2022
👷 Build images with images

👷 Build images with images. About Tiler is a tool to create an image using all kinds of other smaller images (tiles). It is different from other mosa

5.5k Jan 03, 2023
Automatic picture transmission(APT) protocol decoder for NOAA weather satellites

Automatic picture transmission(APT) decoder Automatic picture transmission protocol is used by NOAA satellites. They constantly send a frequency modul

Jayachandra Kasarla 25 Aug 05, 2022
A minimal, standalone viewer for 3D animations stored as stop-motion sequences of individual .obj mesh files.

ObjSequenceViewer V0.5 A minimal, standalone viewer for 3D animations stored as stop-motion sequences of individual .obj mesh files. Installation: pip

csmailis 2 Aug 04, 2022
Fixed Version Of Blender Low Poly Rock Generator For Blender 3.0.0

Blender (3.0.0) - Low Poly Rock Generator This is an addon for Blender 3.0.0 to generate low poly rocks. It was based on an addon that unfortunately h

3 Mar 24, 2022
Convert photos to paintings with python

Convert-photos-to-paintings Before the changes After the changes Before the changes After the changes This code is written in the Python programming l

Amir Hussein Sharifnezhad 3 May 31, 2022
API to help generating QR-code for ZATCA's e-invoice known as Fatoora with any programming language

You can try it @ api-fatoora api-fatoora API to help generating QR-code for ZATCA's e-invoice known as Fatoora with any programming language Disclaime

نافع الهلالي 12 Oct 05, 2022
Alternate Python bindings for the Open Asset Import Library (ASSIMP)

Impasse A simple Python wrapper for assimp using cffi to access the library. Requires Python = 3.7. It's a fork of PyAssimp, Assimp's official Python

Salad Dais 3 Sep 26, 2022
Simple utility to tinker with OPlus images

OPlus image utilities Prerequisites Linux running kernel 5.4 or up (check with uname -r) Image rebuilding Used to rebuild read-only erofs images into

Wiley Lau 15 Dec 28, 2022
An example which streams RGB-D images over spout.

Spout RGB-D Example An example which streams RGB-D images over spout with visiongraph. Due to the spout dependency this currently only works on Window

Florian Bruggisser 4 Nov 14, 2022
Create a static HTML/CSS image gallery from a bunch of images.

gallerize Create a static HTML/CSS image gallery from a bunch of images.

Jochen Kupperschmidt 19 Aug 21, 2022
Generative Art Synthesizer - a python program that generates python programs that generates generative art

GAS - Generative Art Synthesizer Generative Art Synthesizer - a python program that generates python programs that generates generative art. Examples

Alexey Borsky 43 Dec 03, 2022
Python scripts for semi-automated morphometric analysis of atolls from Landsat satellite Imagery.

AtollGeoMorph Python scripts for semi-automated morphometric analysis of atolls from Landsat satellite Imagery. The python scripts included allow user

1 Dec 16, 2022