有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在Android上获得单像素TIFF图像

理想情况下,我需要在我正在开发的Android应用程序上离线访问墨西哥地形的高度信息。我下载了一个。bil文件并将其转换为。tif文件与QGIS一起使用,生成的文件几乎为900 MB

我不知道它是否有效,我仍在学习开发Android应用程序,但我计划将其存储在SD卡中,我想知道是否可以在不读取整个图像的情况下访问单个像素,因为我知道这是不可能的

有人能告诉我这是否可能吗?如果是,怎么做?或者通过其他方式获取我需要的信息,比如转换。将bil文件转换为其他格式或类似的格式

谢谢你的回答


共 (2) 个答案

  1. # 1 楼答案

    Tiff将图像存储为以定义的偏移量开始的字节行。因此,您可以轻松检索单个像素,当然无需加载完整图像。 如果在hex editor中打开任何tif文件,您将看到前4个字节以代码标记tiff。接下来的4个字节给出了tif图像元数据的偏移量。 使用随机访问文件打开图像tif文件,然后查找偏移量,然后进入元数据空间。从这里可以选择所需像素的偏移量。那就去拿吧

    我们的tiff仅用于此目的。即访问单个像素。如果我们需要完整的图像,那么jpeg或BMP就足够了

  2. # 2 楼答案

    检查此链接以获取完整代码:-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);
    }