简体   繁体   English

在Android上获取TIFF图像的单个像素

[英]Get single pixel of TIFF image on Android

I ideally need to have offline access to information of the altitude of the terrain of Mexico on an Android app I'm developing. 理想情况下,我需要在正在开发的Android应用程序上离线访问墨西哥地形的高度信息。 I downloaded a .bil file and converted it to a .tif file with QGIS, and the resulting file is almost 900 MB. 我下载了.bil文件,并使用QGIS将其转换为.tif文件,结果文件将近900 MB。

I don'I know if it would work, I'm still learning to develop Android apps, but I was planning to store it in the SD card and I was wondering if it could be possible to access to a single pixel without reading the whole image, because I know that's impossible. 我不知道它是否行得通,我仍在学习开发Android应用程序,但是我打算将其存储在SD卡中,我想知道是否可以在不读取整个像素的情况下访问单个像素。图片,因为我知道那是不可能的。

Can anyone tell me if it is possible? 谁能告诉我是否有可能? And if it is, how to do it? 如果是的话,该怎么做? Or any other way to get the information I need maybe converting the .bil file to other format or something like that. 或以其他任何方式获取我需要的信息,可能会将.bil文件转换为其他格式或类似格式。

Thanks for answering. 谢谢回答。

Tiff has images stored as rows of bytes starting at defined offsets. Tiff将图像存储为从定义的偏移量开始的字节行。 So you can easily retrieve single pixel and certainly no need to load the full image. 因此,您可以轻松检索单个像素,并且当然不需要加载完整图像。 If you open any tif file in hex editor you will see that first 4 bytes mark tiff by code. 如果在十六进制编辑器中打开任何tif文件,您将看到前4个字节通过代码标记为tiff。 And next 4 bytes give offset for metadata about tif image. 接下来的4个字节给出了有关tif图像的元数据的偏移量。 Use random access file to open image tif file, then seek the offset and you land into metadata space.From here you can pick offset of required pixel. 使用随机访问文件打开图像tif文件,然后寻找偏移量并进入元数据空间。从此处可以选择所需像素的偏移量。 Then go and get it.. 然后去拿吧..

We have tiff for this purpose only. 我们仅出于此目的。 That is to access individual pixels. 那就是访问单个像素。 If we needed full load of image then jpeg or BMP was enough. 如果我们需要图像的全部负载,那么jpeg或BMP就足够了。

check this link for full code:- full example to decode tiff image 检查此链接以获取完整代码:- 解码tiff图像的完整示例

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM