2017-04-19 89 views
0

我理想的情況是需要在我正在開發的Android應用程序上離線訪問墨西哥地形高度信息。我下載了一個.bil文件,並用QGIS將它轉換爲.tif文件,生成的文件大約爲900 MB。在Android上獲取TIFF圖像的單個像素

我不知道它是否可以工作,我仍在學習開發Android應用程序,但是我打算將它存儲在SD卡中,我想知道是否可以訪問單個像素沒有閱讀整個圖像,因爲我知道這是不可能的。

誰能告訴我,如果有可能嗎?如果是這樣,該怎麼做?或者任何其他方式來獲取我需要的信息也許將.bil文件轉換爲其他格式或類似的東西。

感謝您的回答。

+0

我不能回答部分的.tif閱讀,但一個有效的替代辦法是建立一個包含所有X/Y /顏色的數據庫創建腳本圖像的值,然後在需要正確的顏色時與該數據庫進行簡單交互。 – Guardanis

回答

0

Tiff將圖像存儲爲以定義的偏移量開始的字節行。因此,您可以輕鬆檢索單個像素,並且無需加載完整圖像。 如果你在十六進制編輯器中打開任何tif文件,你會看到前4個字節由代碼標記tiff。接下來的4個字節給出了有關tif圖像的元數據的偏移量。 使用隨機訪問文件打開圖像tif文件,然後尋找偏移量,然後登錄到元數據空間。從這裏您可以選擇所需像素的偏移量。然後去得到它..

我們只爲此目的tiff。這是訪問個別像素。如果我們需要滿載圖像,那麼jpeg或BMP就足夠了。

0

檢查此鏈接全碼: - full example to decode tiff image

package com.tif; 

    import android.os.*;import android.content.*;import android.app.*;import     android.widget.*;import android.view.*; 
    import android.view.View.*;import android.graphics.*;import java.io.*;import java.util.*;import android.util.*; 
    import java.lang.*;import java.nio.*;import java.nio.channels.*; 

    public class Main extends Activity 
    { 
private static final int CLEAR_CODE = 256; 
private static final int EOI_CODE = 257; 
long bytesCount=0L; 

    ScrollView sv;TextView tv;ImageView iv; 
    List intList; 
    long[] stripOffs,stripBytes; 
    byte[] bytes,ubytes,bmpBytes; 
    ByteBuffer bBuff; 
    BitBuffer bitBuff; 

    int entries,type,tag; 
    long count,value,ifd,stripAt,stripCount,stripBytesAt,rows,cols; 
    String txt="Null",path="",decompressed=""; 
    String[] info= {"width","length","bitsPerSample","Compression","PhotometricInterpretation","FillOrder","StripOffsets","SamplesPerPixel","RowsPerStrip" 
      ,"StripBytes","XResolution","YResolution","PlanarConfig","ResolutionUnit","extra","NextIFD"}; 
    Bitmap bmp=null; 


    class DotsView extends View 
    { 
     int i = 0;Bitmap bmp;Canvas cnv;Rect bounds;Paint p;int width,height; 
     int alfa,red,green,blue; 
     public DotsView(Context context ,int width ,int height) 
     { 
      super(context); 
      this.width = width; 
      this.height = height; 
      bmp = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888); 
       cnv = new Canvas(bmp); 
       bounds = new Rect(0 , 0, width,height); 
       p = new Paint(); 
      } 

     @Override 
      protected void onDraw(Canvas c) 
     { 

     for(int i=0;i<width;i++) 
      for(int j=0;j<height;j++) 
      { 
     for(int pix=0;pix<3;pix++) 
     { 
     if(pix==0)blue=bmpBytes[i+j+pix]; 
     if(pix==1)green=bmpBytes[i+j+pix]; 
     if(pix==2)red=bmpBytes[i+j+pix]; 
    } 

p.setColor(Color.argb(255, red,green,blue)); 
cnv.drawPoint(i,j, p); 
} 
     c.drawBitmap(bmp, null, bounds , null); 
     invalidate(); 
} 
} 

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]; 
} 
public void extractTif() 
{ 
    String taginfo="";String strVal=""; 
    FileInputStream fis;BufferedInputStream bis;DataInputStream dis; 
    path=Environment.getExternalStorageDirectory().getPath(); 
    path=path+"/DCIM"+"/kpd.tif"; 
    try  { 
     fis=new FileInputStream(path);bis=new BufferedInputStream(fis);dis=new DataInputStream(bis); 
     dis.skip(4);ifd=myInt(dis.readInt()); 
     txt="TIFF-IFD: "; txt=txt+ifd; 
     dis.skip(ifd-8); entries=myShort(dis.readShort()); 
     txt=txt+"\nNo.OfEntries="+entries; 
     for(int i=0;i<=entries;i++) 
      { tag=myShort(dis.readShort());taginfo=tagInfo(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")){stripAt=value;stripCount=count;} 
       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(); 
} 

public void extractBMP() 
{try{ File f=new File(path);RandomAccessFile raf=new RandomAccessFile(f,"r"); 

    raf.seek(stripAt);stripOffs=new long[(int)stripCount]; 
    txt=txt+"\nArray Of Image Offsets="; 
    for(int i=0;i<stripCount;i++){stripOffs[i]=myInt(raf.readInt()); txt=txt+","+stripOffs[i]; } 
    raf.seek(stripBytesAt); stripBytes=new long[(int)stripCount]; 
    txt=txt+"\nArray Of Strip Bytes ="; 
    for(int i=0;i<stripCount;i++){stripBytes[i]=myInt(raf.readInt()); txt=txt+","+stripBytes[i];bytesCount+=stripBytes[i];} 
    txt=txt+stripBytes; 

    bBuff =ByteBuffer.allocate((int)(rows*cols*3)); 
    for(int i=0;i<stripCount;i++) 
    { 
     bytes =new byte[(int)stripBytes[i]]; 
     raf.seek(stripOffs[i]); 
     raf.read(bytes); 
     bBuff.put(lzwUncompress(bytes)); 
     bytes=null; 
    } 

    txt=txt+"\nBuffered Image Bytes Size="+bBuff.position();  
    bBuff.rewind(); 
    bmpBytes=new byte[bBuff.remaining()]; 
    bmpBytes=bBuff.array(); 
    txt=txt+"\nCount of bmpBytes="+bmpBytes.length; 

    bmp=BitmapFactory.decodeByteArray(bmpBytes,0,bmpBytes.length); 

    SystemClock.sleep(5000); 

    txt=txt+"Bitmap Object, bmp="+bmp; 
    if(bmp!=null){iv.setImageBitmap(bmp);sv.addView(iv);} 
    raf.close(); 

     }catch(Exception e){txt=txt+"\nerror="+e.toString();} 
} 
public void lzw() 
{ 
    //String[] table=new String[4096]; 
    byte b;char ch;String s;String pre="";short sh; 
    //List strTable=Arrays.asList(table); 
    //for(int i=0;i<255;i++)table[i]=Character.toString((char)i); 

    for(int i=0;i<100;i++) 
    { 
     b=bytes[i]; 
     if(b<0)sh=(short)(128+b); 
     else sh=(short)b; 
     //ch=(char)b; 
     s=String.valueOf(sh); 
     //s=s+pre; 
     //if(strTable.contains(s)){pre=s;} 
     //else{ } 
     txt=txt+"Byte No."+i+"="+s+" "; 
    } 
} 
public void onCreate(Bundle bnd) 
{ 
    super.onCreate(bnd); 

    extractTif(); 

    //sv=new ScrollView(this); 
    //tv=new TextView(this); 
    //iv=new ImageView(this); 

    //tv.setTextSize(7); 
    //sv.addView(tv); 
    //sv.addView(iv); 

    //tv.setText(txt); 

    //setContentView(sv); 

    Point res=new Point(); getWindowManager().getDefaultDisplay().getSize(res); 

    DotsView myView = new DotsView(this,res.x,res.y); 
    setContentView(myView); 
}