【问题标题】:How to converting TIFF image file to Bitmap Android如何将 TIFF 图像文件转换为 Android 位图
【发布时间】:2015-03-18 14:22:18
【问题描述】:

我想将 SD 卡上的图像转换为位图。我正在使用下面的代码

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

此代码适用于扩展名为 .jpg 或 .png 的文件,但不适用于 .tif 或 .tiff。对于 TIFF 文件,bm变为 null 无异常,所有文件路径均有效。

Android BitmapFactory 在解码 TIFF 图像方面是否有任何限制?

也试过decodeByteArray and decodeStream,对我来说似乎是个限制。​​ 我可以将 TIFF 图像文件读取为byte [],但是将字节 [] 或文件输入流转换为位图返回 null

请告诉我任何其他将 TIFF 图像文件转换为位图的方法。

【问题讨论】:

标签: java android android-activity bitmap android-bitmap


【解决方案1】:

正如 VERT9x 所说,Android 不支持 TIFF 文件。但是您可以使用像 https://github.com/puelocesar/android-lib-magick 这样的原生 android 库来回转换它们。这是将 jpg 转换为 tif 的示例代码。希望这会有所帮助。

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();

【讨论】:

    【解决方案2】:

    Android 本身不支持 TIFF 文件。查看supported media formats的列表。

    如果您想支持 TIFF 文件,您必须自己手动解码它们或找到一个为您解码的库。

    【讨论】:

      【解决方案3】:

      解码一个简单的彩色 tif 文件如下:

          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];
      }
      

      如果您想查看完整代码,请参见此处: Decode Tiff Image in Android Java Code

      【讨论】:

        【解决方案4】:

        尝试使用我的库。它支持从 tiff 直接转换为 jpg/png/bmp https://github.com/Beyka/Android-TiffBitmapFactory

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多