0

I would like to convert images on SDcard to bitmap. I am using below code

String filepath = "/storage/emulated/0/Download/sample2.tif";
    Bitmap bm = BitmapFactory.decodeFile(filepath);

This code is working fine for file with extension .jpg or .png but not for .tif or .tiff. For TIFF files bmbecomes null no exceptions nothing all file paths are valid.

Is there any limitation in Android BitmapFactory with respect to decoding TIFF images?

Also tried decodeByteArray and decodeStream, looks like limitation for me. I am able to read TIFF image file as byte [] but conversion of byte[] or file input stream as bitmap is returning null

Please let me know any other way to convert TIFF Image file to Bitmap.

Ganesh K
  • 2,623
  • 9
  • 51
  • 78
  • possible duplicate of [Is there a equivalent of Android's BitmapFactory.Options isDecodeBounds for TIFF in Java/JAI?](http://stackoverflow.com/questions/15645174/is-there-a-equivalent-of-androids-bitmapfactory-options-isdecodebounds-for-tiff) – GreyBeardedGeek Mar 18 '15 at 14:31
  • 1
    I don't believe `BitMapFacotry` supports TIFF. The TIFF format is quite a complex file format (supports virtually unlimited combinations of bit depths, number of channels, compression algorithms etc). You probably want to use libTiff, rather than implementing it yourself (unless you really like to do such things, like me... :-) ). – Harald K Mar 18 '15 at 14:31
  • @GreyBeardedGeek No, I don't think that's related. – Harald K Mar 18 '15 at 14:32

4 Answers4

1

As VERT9x said TIFF files are not supported on android. But you can convert them back or forth using native android library like https://github.com/puelocesar/android-lib-magick . This is sample code to convert jpg to tif. Hope this helps.

MagickImage Image = new MagickImage(new ImageInfo(IMAGE_PATH));
// Image = Image.scaleImage(800, 800);
Image.setImageFormat("tif");
Image.setFileName(str);
ImageInfo localImageInfo = new ImageInfo(str);
localImageInfo.setMagick("tif");
Image.writeImage(localImageInfo);
// store as tif
byte[] blob = Image.imageToBlob(localImageInfo);
FileOutputStream localFileOutputStream = new FileOutputStream(str);
localFileOutputStream.write(blob);
localFileOutputStream.close();
1

To decode a simple color tif file go as below:

    String taginfo="";String strVal=""; //These are Tiff Tags

    FileInputStream fis;BufferedInputStream bis;DataInputStream dis;

    path=Environment.getExternalStorageDirectory().getPath();   
    path=path+"/DCIM"+"/fileName.tif";  //whatever is your file-name.tif

    try{
         fis=new FileInputStream(path);
         bis=new bufferedInputStream(fis);
         dis=new DataInputStream(bis);

         dis.skip(4);              //skip 4 byte marker of TIFF+endian
         ifd=myInt(dis.readInt()); //read the 4 byte IFD-location

         txt="TIFF-IFD: "; //txt is the final text displayed in textView
         txt=txt+ifd;
         dis.skip(ifd-8); 
         entries=myShort(dis.readShort()); //read in your endian-style  
         txt=txt+"\nNo.OfEntries="+entries;

         for(int i=0;i<=entries;i++)
           {    
            tag=myShort( dis.readShort() );
            taginfo=tagInfo(tag); //tagInfo function returns info associated 
                                   //with tag
            type=myShort( dis.readShort() );
            count=myInt( dis.readInt() );
            value=myInt( dis.readInt() ); 

            if(type==3)strVal="Value="; else strVal="Offset=";

            if( strVal.equals("Offset=") )
            {
                if( taginfo.equals("StripOffsets") )   //image is stored as
                    {stripAt=value;stripCount=count;}  // strips of rows

                if( taginfo.equals("StripBytes")   )
                    {stripBytesAt=value;}
            }

            if( taginfo.equals("width") ){cols=value;}

            if( taginfo.equals("length") ){rows=value;}

            txt=txt+"\ntag="+tag+"" + tagInfo(tag) + ",type=" + type +  
                    ",count=" + count + strVal + value;
           }
         dis.close();bis.close();fis.close(); 

        }catch(Exception e)     { txt = txt + "\nerror=" + e.toString(); }

    txt=txt+"\nNo.OfStrips="+stripCount+",array of strip locations at: 
        "+stripAt+" and array of bytesPerStrip at "+stripBytesAt ;

    extractBMP(); // a function you will define to combine all strips to 
                   //bitmap image
}


public int myShort(short sh)
{   int i;
    ByteBuffer shortBuff=ByteBuffer.allocate(4);
    shortBuff.order(ByteOrder.BIG_ENDIAN);shortBuff.putShort(sh);shortBuff.rewind();
    shortBuff.order(ByteOrder.LITTLE_ENDIAN);sh=shortBuff.getShort();
    if(sh<0)i=(int)(sh+32768); else i=(int)sh;
    return i;
}
public long myInt(int i)
{    long l=0L;
     ByteBuffer intBuff=ByteBuffer.allocate(4);
     intBuff.order(ByteOrder.BIG_ENDIAN);intBuff.putInt(i);intBuff.rewind();
     intBuff.order(ByteOrder.LITTLE_ENDIAN); i=intBuff.getInt();
     if(i<0)l=(long)(i+2147483648L);     else l=(long)i; 
     return l;
}
public String tagInfo(int tag)
{   int i=0;
    switch(tag)
    {case 256: i=0;break;case 257: i=1;break;case 258: i=2;break;case 259: i=3;break;case 262: i=4;break;case 266: i=5;break;
        case 273: i=6;break;case 277: i=7;break;case 278: i=8;break;case 279: i=9;break;case 282: i=10;break;case 283: i=11;break;
        case 284: i=12;break;case 296: i=13;break;case 1496: i=14;break;case 0: i=15;break;
    }
    return info[i];
}

If you wish to see the full code then see here: Decode Tiff Image in Android Java Code

0

TIFF files are not supported natively on Android. Check the list of supported media formats.

If you want to support TIFF files you'll have to decode them manually yourself or find a library that does it for you.

VERT9x
  • 372
  • 2
  • 13
0

Try to use my lib. It support dirrect convert from tiff to jpg/png/bmp https://github.com/Beyka/Android-TiffBitmapFactory

Beyka
  • 1,372
  • 1
  • 10
  • 15