TIFF添加坐标信息
来源:互联网 发布:中国 歼31 沙特 知乎 编辑:程序博客网 时间:2024/06/05 15:40
处理tiff图片过程中,需要给TIFF图片加上相应的坐标信息,来表示当前图片的坐标范围。下面就给出如何在一张空白的TIFF图片中添加坐标信息。
1.头文件
#pragma once#include"tiflib.h"#include<string>#include <vector>#include <algorithm> using namespace std;#define TIFF_HEADER_SIZE 8 //文件头字节数#define DE_START 10 //tiff TAG开始的位置#define ONE_DE_SIZE 12 //每个TAG的大小#define IDF_END_FLAG_SIZE 4 //IFD最后结尾的4个空字节typedef struct{ int i_tag; const char* text;}TagText;typedef struct{ TIFF_UINT16_T type; char* type_name; TIFF_UINT16_T type_size;}DataType;typedef struct{ TIFF_UINT16_T tag; TIFF_UINT16_T type; TIFF_UINT32_T count; TIFF_UINT32_T offset;}DirectoryEntry;typedef struct{ DirectoryEntry de; int data_source; //0 - offset本身值 1 - offset对应的源文件偏移量 2 - 来自内存 TIFF_UINT8_T* mem_data; //当 data_soure = 2 时 ,指向内存}deInfo;class tiffTrans{public: tiffTrans(); tiffTrans( const char* tiff_path ); ~tiffTrans();public: int open( const char* tiff_path ); void coord_box( geoRECT geo_rect ); int save_to_trans( const char* new_path = NULL );protected: int arrangement();//0 - tile 1 - line bool analysis( char* ret_error ); //分析tiff是否可以进行转换 true - 可以 false - 不可以 private: string new_tiff_name(); void write_file_header(); TIFF_UINT64_T double_to_long( double d_ ); void cs_pixel_scale( double cx , double cy ); void cs_tie_point( double x , double y ); void cs_coord( deInfo* coord_list ); int get_src_tag_list(); const char* tag_text( int i_tag ); deInfo* cts_strip_offsets(); deInfo* cts_rows_per_strip(); deInfo* cts_strip_byte_counts(); deInfo* cts_line_tag(); deInfo* delete_coord_tag(); int cts_new_tag_list(); void print_tag_info_list(); void write_tag_list(); void modify_strip_offset(); void modify_line_strip(); void modify_tile_strip(); void sort_byte_order( TIFF_UINT8_T* buf , TIFF_UINT16_T data_type , TIFF_UINT16_T data_count ); TIFF_UINT64_T file_disk_data( DirectoryEntry de , TIFF_UINT64_T buffer_size ); void write_img_data(); void write_img_data2(); void write_line_img(); void write_tile_img(); void write_data( TIFF_UINT32_T data_start , TIFF_UINT32_T data_size );private: FILE* _tile_tiff; FILE* _line_tiff; TiffFile* _tiff_src; string _src_name; TIFF_UINT64_T _current_file_point; //写入当前文件操作的指针 deInfo* de_list; TIFF_UINT16_T _de_num; //标签的数量 int _coord_tag_num; //包含坐标信息的TAG的数量 TIFF_UINT32_T _strip_offset_pos; //TAG StripOffset or TileOffset 的文件偏移位置 TIFF_UINT32_T _count_one_offset_pos; TIFF_UINT64_T pixel_scale[3];//像元比例 TIFF_UINT64_T tie_point[6];//控制点坐标对 geoRECT _geo_rect;};
2.cpp文件
#include "tifftrans.h"TagText tag_text_list[] ={ { 254 , "NewSubfileType" }, { 256 , "ImageWidth" }, { 257 , "ImageLength" }, { 258 , "BitsPerSample" }, { 259 , "Compression" }, { 262 , "PhotometricInterpretation" }, { 273 , "StripOffsets" }, { 274 , "相对于图像的行和列的方向" }, { 277 , "SamplesPerPixel" }, { 278 , "RowsPerStrip" }, { 279 , "StripByteCounts" }, { 282 , "XResolution" }, { 283 , "YResolution" }, { 284 , "PlanarConfiguration" }, { 296 , "ResolutionUnit" }, { 305 , "Software" }, { 306 , "DateTime" }, { 322 , "TileWidth" }, { 323 , "TileLength" }, { 324 , "TileOffsets" }, { 325 , "TileByteCounts" }, { 339 , "SampleFormat" }, { 33550 , "ModelPixelScaleTag" }, { 33922 , "ModelTiepointTag" }, { 34264 , "ModelTransformationTag" }, { 34735 , "GeoKeyDirectoryTag" }, { 34736 , "GeoDoubleParamsTag" }, { 34737 , "GeoAsciiParamsTag" }, { -1 , "" }};DataType data_type_list[] ={ { 0 , "NULL" , 0 },//NULL { 1 , "BYTE" , 1 },//BYTE 8-bit unsigned integer { 2 , "ASCII" , 1 },//ASCII 8-bit byte that contains a 7-bit ASCII code; the last byte must be NUL (binary zero) { 3 , "SHORT" , 2 },//SHORT 16-bit (2-byte) unsigned integer { 4 , "LONG" , 4 },//LONG 32-bit (4-byte) unsigned integer { 5 , "RATIONAL" , 8 },//RATIONAL Two LONGs: the first represents the numerator { 6 , "SBYTE" , 1 },//SBYTE An 8-bit signed (twos-complement) integer. { 7 , "UNDEFINED", 1 },//UNDEFINED An 8-bit byte that may contain anything, depending on the definition of the field. { 8 , "SSHORT" , 2 },//SSHORT A 16-bit (2-byte) signed (twos-complement) integer { 9 , "SLONG" , 4 },//SLONG A 32-bit (4-byte) signed (twos-complement) integer { 10 , "SRATIONAL", 8 },//SRATIONAL Two SLONG’s: the first represents the numerator of afraction, the second the denominator { 11 , "FLOAT" , 4 },//FLOAT Single precision (4-byte) IEEE format { 12 , "DOUBLE" , 8 } //DOUBLE Double precision (8-byte) IEEE format.};tiffTrans::tiffTrans(){ _tiff_src = new TiffFile; memset( _tiff_src , 0 , sizeof(TiffFile) ); _coord_tag_num = 0 ;}tiffTrans::tiffTrans( const char* tiff_path ){ _src_name = tiff_path; _tiff_src = new TiffFile; memset( _tiff_src , 0 , sizeof(TiffFile) ); _coord_tag_num = 0 ;}tiffTrans::~tiffTrans(){ if ( _tiff_src != NULL ) { delete _tiff_src; _tiff_src = NULL; }}int tiffTrans::open( const char* tiff_path ){ _src_name = tiff_path; int ret = tif_open( tiff_path , _tiff_src ); _tile_tiff = _tiff_src->pfile; return ret;}void tiffTrans::coord_box( geoRECT geo_rect ){ _geo_rect = geo_rect; double scaleX = ( _geo_rect.right - _geo_rect.left ) / _tiff_src->tif_width; double scaleY = ( _geo_rect.top - _geo_rect.botton ) / _tiff_src->tif_height; cs_pixel_scale( scaleX , scaleY ); cs_tie_point( _geo_rect.left , _geo_rect.top );}int tiffTrans::arrangement(){ if( _tiff_src->tile.is_tile == true ) { return 0; } else { return 1; }}const char* tiffTrans::tag_text( int i_tag ){ int i = 0 ; while ( tag_text_list[i].i_tag != -1 ) { if ( tag_text_list[i].i_tag == i_tag ) { return tag_text_list[i].text; } i++; } return "";}void tiffTrans::write_file_header( ){ //字节序 fwrite( "II" , 2 , 1 , _line_tiff ); //版本号 TIFF_UINT16_T ver = 0x002a; fwrite( &ver , 2 , 1 , _line_tiff ); //Tag偏移量 TIFF_UINT32_T offset = 0x00000008; fwrite( &offset , 4 , 1 , _line_tiff );}bool tiffTrans::analysis( char* ret_error ){ bool b = true; if ( _tiff_src->bit_per_samples == 1 ) { strcpy( ret_error , "错误:这是一张1位图片" ); b = false; } else if ( _tiff_src->bit_per_samples == 4 ) { strcpy( ret_error , "错误:这是一张4位图片" ); b = false; } else if ( _tiff_src->bit_per_samples == 8 ) { strcpy( ret_error , "错误:这是一张8位图片" ); b = false; } if ( _tiff_src->compression != 1 ) { strcpy( ret_error , "错误:这是一张经过压缩的图片" ); b = false; } if( _tiff_src->planar_config != 1 ) { strcpy( ret_error , "错误:Planar Config 为 Sperate ,暂时无法处理" ); b = false; } if ( _tiff_src->tile.is_tile == false ) { strcpy( ret_error , "错误:TIFF按线性方式排列数据" ); b = false; } return b;}string tiffTrans::new_tiff_name(){ int pos = _src_name.rfind( '\\' ); string tiff_name = _src_name.substr( pos + 1 ); string dir = _src_name.substr( 0 , pos + 1 ); string temp_name = "line_"; temp_name += tiff_name ; return ( dir + temp_name ) ;}int tiffTrans::get_src_tag_list(){ TIFF_UINT32_T ifd_offset; //第一个IFD的偏移量 fseek( _tile_tiff , 0 , SEEK_SET ); fseek( _tile_tiff ,4 ,SEEK_SET ); ifd_offset = get4( _tile_tiff , _tiff_src->tiff_byte_order ) ; //定位到IFD的位置 fseek( _tile_tiff , ifd_offset , SEEK_SET ); //得到IFD的数量 _de_num = get2( _tile_tiff , _tiff_src->tiff_byte_order ); de_list = new deInfo[ _de_num ]; memset( de_list , 0 , _de_num * sizeof( deInfo ) ); //循环得到DE for ( TIFF_UINT16_T i = 0x0000 ; i < _de_num ; i++ ) { fseek( _tile_tiff , ifd_offset + ONE_DE_SIZE * i + 2 , SEEK_SET );//文件指针复原指向 de_list[i].de.tag = get2( _tile_tiff , _tiff_src->tiff_byte_order ); de_list[i].de.type = get2( _tile_tiff , _tiff_src->tiff_byte_order ); de_list[i].de.count = get4( _tile_tiff , _tiff_src->tiff_byte_order ); //如果是大端字节序并且是short类型,则只会读取四个字节中的前两个字节 if ( de_list[i].de.type == 3 && _tiff_src->tiff_byte_order == 0x4d4d/*Motor*/ && de_list[i].de.count == 1 ) { de_list[i].de.offset = (TIFF_UINT32_T)get2( _tile_tiff , _tiff_src->tiff_byte_order ); } else { de_list[i].de.offset = get4( _tile_tiff , _tiff_src->tiff_byte_order ); } //如果是 SHORT 或者 LONG 并且数量为1,则直接存储在Offset中,并不存储地址 if( ( de_list[i].de.type == 3 || de_list[i].de.type == 4 ) && de_list[i].de.count == 1 ) { de_list[i].data_source = 0 ; } else { de_list[i].data_source = 1 ; } if ( de_list[i].de.tag == 33550 || de_list[i].de.tag == 33922 || de_list[i].de.tag == 34735 || de_list[i].de.tag == 34736 || de_list[i].de.tag == 34737)//关于坐标的TAG { _coord_tag_num ++ ; } } print_tag_info_list(); return _de_num ;}deInfo* tiffTrans::cts_strip_offsets(){ deInfo* temp_de = new deInfo; temp_de->de.tag = 273; temp_de->de.type = 4;//long temp_de->de.count = _tiff_src->tif_height; temp_de->de.offset = 0; temp_de->data_source = 2; TIFF_UINT32_T* mem = new TIFF_UINT32_T[_tiff_src->tif_height]; memset( mem , 0 , sizeof(TIFF_UINT32_T)*_tiff_src->tif_height ); temp_de->mem_data = (TIFF_UINT8_T*)mem; return temp_de;}deInfo* tiffTrans::cts_rows_per_strip(){ deInfo* temp_de = new deInfo; temp_de->de.tag = 278; temp_de->de.type = 3;//short temp_de->de.count = 1; temp_de->de.offset = 1; temp_de->data_source = 0; temp_de->mem_data = NULL; return temp_de;}deInfo* tiffTrans::cts_strip_byte_counts(){ deInfo* temp_de = new deInfo; temp_de->de.tag = 279; temp_de->de.type = 4;//short temp_de->de.count = _tiff_src->tif_height; temp_de->de.offset = 0; temp_de->data_source = 2; TIFF_UINT32_T* mem = new TIFF_UINT32_T[_tiff_src->tif_height]; memset( mem , 0 , sizeof(TIFF_UINT32_T)*_tiff_src->tif_height ); for ( int i = 0 ; i < _tiff_src->tif_height ; i++ ) { mem[i] = _tiff_src->tif_width * _tiff_src->samples_per_pixel; } temp_de->mem_data = (TIFF_UINT8_T*)mem; return temp_de;}deInfo* tiffTrans::cts_line_tag(){ deInfo* temp_line_tag_list = new deInfo[3]; memset( temp_line_tag_list , 0 , sizeof(deInfo) * 3 ); deInfo* temp = cts_strip_offsets(); memcpy( temp_line_tag_list , temp , sizeof(deInfo) ) ; delete temp; temp = cts_rows_per_strip(); memcpy( temp_line_tag_list + 1 , temp , sizeof(deInfo)); delete temp; temp = cts_strip_byte_counts(); memcpy( temp_line_tag_list + 2 , temp , sizeof(deInfo)); delete temp; temp = NULL; return temp_line_tag_list;}deInfo* tiffTrans::delete_coord_tag(){ deInfo* temp_de_list = new deInfo[ _de_num - _coord_tag_num ];//删除坐标TAG memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num - _coord_tag_num ) ); int j = 0; for ( int i = 0 ; i < _de_num ; i ++ ) { if ( ( de_list[i].de.tag != 33550 )&& ( de_list[i].de.tag != 33922 )&& ( de_list[i].de.tag != 34735 )&& ( de_list[i].de.tag != 34736 )&& ( de_list[i].de.tag != 34737 ) ) { memcpy ( temp_de_list + j , de_list + i , sizeof(deInfo) ); j++; } } delete[] de_list; de_list = NULL; de_list = temp_de_list; _de_num -= _coord_tag_num ; return de_list;}int tiffTrans::cts_new_tag_list( ){ delete_coord_tag( );//删除所有的关于坐标的TAG deInfo* temp_line = new deInfo[2]; memset( temp_line , 0 , 2 * sizeof( deInfo ) ); cs_coord( temp_line ); deInfo* temp_de_list = new deInfo[ _de_num + 2 ];//tile 4个标签 line 只需要3个标签 memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num + 2 ) ); int j = 0 , k = 0 ; for ( int i = 0 ; i < _de_num ; i++ ) { if ( k < 2 )//只有二个标签 { if ( de_list[i].de.tag < temp_line[k].de.tag ) { memcpy( temp_de_list + j , de_list + i , sizeof( deInfo ) ); j++; } else { memcpy( temp_de_list + j , temp_line + k , sizeof( deInfo ) ); j++; k++; i--; } } else { memcpy( temp_de_list + j , de_list + i , sizeof( deInfo ) ); j++; } } if ( k < 2 ) { int temp = k; for ( int i = temp ; i < 2 ; i++ ) { temp_de_list[ j ] = temp_line[ k ]; j ++; k ++; } } delete[] de_list; de_list = NULL; de_list = temp_de_list; _de_num += 2; print_tag_info_list(); return 0;}void tiffTrans::print_tag_info_list(){ printf( "\n" ); for ( int i = 0 ; i < _de_num ; i++ ) { char outStr[1024]; memset( outStr , 0 , 1024 * sizeof( char ) ); sprintf( outStr , "0x%04x[ %5d %-26s ] , 0x%02x , 0x%04x( %5d ) , 0x%08x , %d \n" , de_list[i].de.tag , de_list[i].de.tag , tag_text( de_list[i].de.tag ) , de_list[i].de.type , de_list[i].de.count , de_list[i].de.count , de_list[i].de.offset , de_list[i].data_source ) ; printf( outStr ); }}void tiffTrans::write_tag_list(){ _strip_offset_pos = 0; _count_one_offset_pos = 0; for ( int i = 0 ; i < _de_num ; i++ ) { fseek( _line_tiff , DE_START + ONE_DE_SIZE * i , SEEK_SET ); fwrite( &( de_list[i].de.tag ) , 2 , 1 , _line_tiff ); //TAG 2字节 fwrite( &( de_list[i].de.type ) , 2 , 1 , _line_tiff ); //数据类型 2字节 fwrite( &( de_list[i].de.count ) , 4 , 1 , _line_tiff ); //count 4字节 if( ( de_list[i].de.tag == 273 || de_list[i].de.tag == 324 ) && de_list[i].de.count > 1 )//Strip offset or TileOffset { fseek( _line_tiff , 0 , SEEK_END ); _strip_offset_pos = ftell( _line_tiff ); } else if( de_list[i].de.tag == 273 && de_list[i].de.count == 1 )//Strip offset or TileOffset值保存在OFFSET中 { fseek( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET ); _count_one_offset_pos = ftell( _line_tiff ); fseek( _line_tiff , 0 , SEEK_END ); } //写入offset if( de_list[i].data_source == 0 )//直接写入值 { fwrite( &( de_list[i].de.offset ) , 4 , 1 , _line_tiff ); } else if ( de_list[i].data_source == 1 )//文件对应的偏移量 { fseek( _line_tiff , 0 , SEEK_END ); TIFF_UINT32_T pos = ftell( _line_tiff ); TIFF_UINT64_T buffer_size = data_type_list[de_list[i].de.type].type_size * de_list[i].de.count; file_disk_data( de_list[i].de , buffer_size ); //修改TAG对应的数据存放的地址 fseek( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET ); fwrite( &pos , 1 , 4 , _line_tiff ); } else if ( de_list[i].data_source == 2 )//内存 { fseek( _line_tiff , 0 , SEEK_END ); TIFF_UINT32_T pos = ftell( _line_tiff ); fwrite ( de_list[i].mem_data , 1 , data_type_list[de_list[i].de.type].type_size * de_list[i].de.count , _line_tiff ); //修改TAG对应的数据存放的地址 fseek( _line_tiff , DE_START + ONE_DE_SIZE * i + 8 , SEEK_SET ); fwrite( &pos , 1 , 4 , _line_tiff ); if ( !( ( de_list[i].de.tag == 33550 ) || ( de_list[i].de.tag == 33922 ) ) ) { delete[] de_list[i].mem_data; } } }}TIFF_UINT64_T tiffTrans::file_disk_data( DirectoryEntry de , TIFF_UINT64_T buffer_size ){ fseek( _tile_tiff , de.offset , SEEK_SET ); TIFF_UINT8_T* buf = new TIFF_UINT8_T[1024]; memset( buf , 0 , 1024 ); TIFF_UINT64_T fs = 0; TIFF_UINT16_T read_size = 0; if ( buffer_size <= 1024 )//若小于1024字节,则读取之后直接写入即可 { read_size = fread( buf , 1 , buffer_size , _tile_tiff ); if( _tiff_src->tiff_byte_order == TIFF_BIGENDIAN && data_type_list[de.type].type_size != 1 ) { sort_byte_order( buf , de.type , de.count ); } fs += fwrite ( buf , 1 , read_size , _line_tiff ); } else//若大于1024字节,则分批写入1024字节,最后写入不足1024的字节 { TIFF_UINT16_T tile_num = ( int )(buffer_size / 1024) ; TIFF_UINT16_T last_num = buffer_size % 1024; for ( int i = 0 ; i < tile_num ; i++ ) { read_size = fread( buf , 1 , 1024 , _tile_tiff );//注意参数的顺序 if( _tiff_src->tiff_byte_order == TIFF_BIGENDIAN && data_type_list[de.type].type_size != 1 ) { sort_byte_order( buf , de.type , de.count ); } fs += fwrite ( buf , 1 , read_size , _line_tiff ); } read_size = fread( buf , 1 , last_num , _tile_tiff ); if( _tiff_src->tiff_byte_order == TIFF_BIGENDIAN && data_type_list[de.type].type_size != 1 ) { sort_byte_order( buf , de.type , de.count ); } fs += fwrite ( buf , 1 , last_num , _line_tiff ); } delete[] buf; buf = NULL; return fs;}void tiffTrans::sort_byte_order( TIFF_UINT8_T* buf , TIFF_UINT16_T data_type , TIFF_UINT16_T data_count ){ TIFF_UINT8_T* p = buf; for ( TIFF_UINT16_T i = 0 ; i < data_count ; i++ ) { if ( data_type == 3 || data_type == 8 )//SHORT { TIFF_UINT16_T ret = sget2( p , TIFF_BIGENDIAN ); memcpy( p , &ret , 2 ); p += 2; } else if ( data_type == 4 || data_type == 9 || data_type == 11 )//LONG { TIFF_UINT32_T ret = sget4( p , TIFF_BIGENDIAN ); memcpy( p , &ret , 4 ); p += 4; } if ( data_type == 5 || data_type == 10 ) { TIFF_UINT32_T ret = sget4( p , TIFF_BIGENDIAN ); memcpy( p , &ret , 4 ); p += 4; ret = sget4( p , TIFF_BIGENDIAN ); memcpy( p , &ret , 4 ); p += 4; } else if ( data_type == 12 )//DOUBLE { TIFF_UINT64_T ret = sget8( p , TIFF_BIGENDIAN ); memcpy( p , &ret , 8 ); p += 8; } }}void tiffTrans::modify_line_strip(){ fseek( _line_tiff , 0 , SEEK_END ); TIFF_UINT32_T current_size = ftell( _line_tiff ); if( _count_one_offset_pos > 0 )//Strip offset or TileOffset值保存在OFFSET中 { fseek( _line_tiff , _count_one_offset_pos , SEEK_SET ); fwrite( ¤t_size , 1 , 4 , _line_tiff ); } else if ( _strip_offset_pos > 0 ) { fseek( _line_tiff , _strip_offset_pos , SEEK_SET ); for ( int i = 0 ; i < _tiff_src->bcount_strip_offset ; i++ ) { TIFF_UINT32_T offset_pos = current_size + i * _tiff_src->strip_byte_counts[i]; fwrite( &offset_pos , 1 , 4 , _line_tiff ); } }}void tiffTrans::modify_tile_strip(){ fseek( _line_tiff , 0 , SEEK_END ); TIFF_UINT32_T current_size = ftell( _line_tiff ); fseek( _line_tiff , _strip_offset_pos , SEEK_SET ); TIFF_UINT32_T tile_bytes = _tiff_src->tile.tile_height * _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel ; TIFF_UINT32_T tile_satrt = current_size ; for ( int i = 0 ; i < _tiff_src->tile.tile_offset_count ; i++ ) { TIFF_UINT32_T tile_satrt = current_size ; tile_satrt += i * tile_bytes ; fwrite( &tile_satrt , 1 , 4 , _line_tiff ); }}void tiffTrans::modify_strip_offset(){ if( _tiff_src->tile.is_tile ) { modify_tile_strip( ); } else { modify_line_strip( ); }}void tiffTrans::write_img_data(){ int table_w = (int)( _tiff_src->tif_width / _tiff_src->tile.tile_width ); if ( _tiff_src->tif_width % _tiff_src->tile.tile_width > 0 ) { table_w ++ ; } int table_h = (int)( _tiff_src->tif_height/ _tiff_src->tile.tile_height)+1; if ( _tiff_src->tif_height % _tiff_src->tile.tile_height > 0 ) { table_h ++ ; } fseek( _line_tiff , 0 , SEEK_END ); TIFF_UINT64_T cur_size = ftell( _line_tiff ); for( int i_height = 0 ; i_height < _tiff_src->tif_height ; i_height++ )//按行添加 { system("cls"); printf( "%s\n Tile -> Line %d / %d \n" ,_src_name.c_str(), i_height+1 , _tiff_src->tif_height ); fseek( _line_tiff , cur_size + i_height * ( _tiff_src->tif_width * _tiff_src->samples_per_pixel ) , SEEK_SET ); int temp_table_h = i_height / _tiff_src->tile.tile_height;//确定tile的行高 int tile_h = i_height % _tiff_src->tile.tile_height; for ( int i_w_table = 0 ; i_w_table < table_w ; i_w_table ++ )//按tile的列填充 { TIFF_UINT32_T table_pos = temp_table_h * table_w + i_w_table; TIFF_UINT32_T table_start = _tiff_src->tile.tile_offset_list[ table_pos ] + ( _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel) *tile_h ; fseek( _tile_tiff , table_start , SEEK_SET ); TIFF_UINT8_T* buf = new TIFF_UINT8_T[ _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel ]; fread( buf , 1 , _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel , _tile_tiff ); fwrite( buf , 1 , _tiff_src->tile.tile_width * _tiff_src->samples_per_pixel , _line_tiff ); delete[] buf; buf = NULL; } }}void tiffTrans::write_img_data2(){ if ( _tiff_src->tile.is_tile ) { write_tile_img( ); } else { write_line_img( ); }}void tiffTrans::write_line_img( ){ fseek( _line_tiff , 0 , SEEK_END ); for ( int i = 0 ; i < _tiff_src->bcount_strip_offset ; i ++ ) { write_data( _tiff_src->strip_line[i] , _tiff_src->strip_byte_counts[i] ); }}void tiffTrans::write_tile_img( ){ fseek( _line_tiff , 0 , SEEK_END ); for ( int i = 0 ; i < _tiff_src->tile.tile_offset_count ; i ++ ) { write_data( _tiff_src->tile.tile_offset_list[i] , _tiff_src->tile.tile_byte_num_list[i] ); }}void tiffTrans::write_data( TIFF_UINT32_T data_start , TIFF_UINT32_T buffer_size ){ fseek( _tile_tiff , data_start , SEEK_SET ); TIFF_UINT8_T* buf = new TIFF_UINT8_T[1024]; memset( buf , 0 , 1024 ); TIFF_UINT16_T read_size = 0; if ( buffer_size <= 1024 )//若小于1024字节,则读取之后直接写入即可 { read_size = fread( buf , 1 , buffer_size , _tile_tiff ); fwrite ( buf , 1 , read_size , _line_tiff ); } else//若大于1024字节,则分批写入1024字节,最后写入不足1024的字节 { TIFF_UINT16_T tile_num = ( int )(buffer_size / 1024) ; TIFF_UINT16_T last_num = buffer_size % 1024; for ( int i = 0 ; i < tile_num ; i++ ) { read_size = fread( buf , 1 , 1024 , _tile_tiff );//注意参数的顺序 fwrite ( buf , 1 , read_size , _line_tiff ); } read_size = fread( buf , 1 , last_num , _tile_tiff ); fwrite ( buf , 1 , last_num , _line_tiff ); } delete[] buf; buf = NULL;}int tiffTrans::save_to_trans( const char* new_path ){ string temp_path; if ( new_path == NULL ) { temp_path = new_tiff_name() ; } else { temp_path = new_path; } _line_tiff = fopen( temp_path.c_str() , "wb" ); if ( _line_tiff == NULL ) { return -1 ; } //1.写入TIFF的文件头 write_file_header( ); //读取原来的TIFF中的TAG标签 get_src_tag_list( ); //生成新的TAG列表 cts_new_tag_list( ); //2.写入tag的数量 fwrite( &( _de_num ) , 1 , 2 , _line_tiff ); //3.写入空的DE占位空间 TIFF_UINT8_T* place_holder = new TIFF_UINT8_T[ _de_num * ONE_DE_SIZE + IDF_END_FLAG_SIZE ]; memset( place_holder , 0 , _de_num * ONE_DE_SIZE + IDF_END_FLAG_SIZE ); fwrite( place_holder , 1 , _de_num * ONE_DE_SIZE + IDF_END_FLAG_SIZE , _line_tiff ); TIFF_UINT64_T write_file_size = ftell( _line_tiff ); //4.写入具体的TAG内容和对应的偏移量 write_tag_list(); //5.修改图像数据的偏移量 modify_strip_offset(); //6.写入图像数据 write_img_data2(); fclose( _line_tiff ); delete[] place_holder; place_holder = NULL; return 0;}TIFF_UINT64_T tiffTrans::double_to_long( double d_ ){ union { TIFF_UINT64_T i; double f; } u; u.f = d_ ; return u.i ;}void tiffTrans::cs_pixel_scale( double cx , double cy ){ pixel_scale[0] = double_to_long ( cx ); pixel_scale[1] = double_to_long ( cy ); pixel_scale[2] = 0 ;}void tiffTrans::cs_tie_point( double x , double y ){ tie_point[0] = 0; tie_point[1] = 0; tie_point[2] = 0; tie_point[3] = double_to_long( x ) ; tie_point[4] = double_to_long( y ) ; tie_point[5] = 0;}void tiffTrans::cs_coord( deInfo* coord_list ){ coord_list[0].de.tag = 33550;//GeoTagPixelScale coord_list[0].de.type = 12;//double coord_list[0].de.count = 3 ; coord_list[0].data_source = 2;//内存数据 coord_list[0].mem_data = ( TIFF_UINT8_T* )pixel_scale; coord_list[1].de.tag = 33922;//GeoTagTiePoint coord_list[1].de.type = 12;//double coord_list[1].de.count = 6 ; coord_list[1].data_source = 2;//内存数据 coord_list[1].mem_data = ( TIFF_UINT8_T* )tie_point;}
3.使用方法:
#include <stdio.h>#include <string>using namespace std;#include "tifftrans.h"string save_name( string str_path , string str_save_dir );int main( int argc, char* argv[] ){ if ( argc < 7 ) { printf( "参数输入的不正确!\n[D:\\xxx.tif] [上] [下] [左] [右] 四个方向上的坐标 [D:\\xxx] " ); return -1; } string str_path( argv[1] ); string str_top ( argv[2] ); string str_botton ( argv[3] ); string str_left ( argv[4] ); string str_right ( argv[5] ); string str_save_dir ( argv[6] ); tiffTrans tiff_trans; tiff_trans.open( str_path.c_str() ); geoRECT geo_box; geo_box.top = atof( str_top.c_str() ); geo_box.botton = atof( str_botton.c_str() ); geo_box.left = atof( str_left.c_str() ); geo_box.right = atof( str_right.c_str() ); tiff_trans.coord_box( geo_box ); tiff_trans.save_to_trans( /*"D:\\123.tiff"*/ save_name( str_path , str_save_dir ).c_str() ); return 0;}string save_name( string str_path , string str_save_dir ){ int pos = str_path.rfind('\\'); string tif_name = str_path.substr( pos + 1 ); string temp = "\\coord_"; temp += tif_name ; return str_save_dir + temp;}
0 0
- TIFF添加坐标信息
- Tiff、jpg图片怎么样添加地理坐标信息
- 讀取tiff文件信息
- TIFF影像的坐标文件.tfw
- TIFF
- TIFF
- 如何给.JPG格式图片添加坐标信息(ArcGIS)
- 【转】tiff/tfw, jpg/jpgw坐标文件的格式
- tiff/tfw, jpg/jpgw坐标文件的格式
- tiff/tfw, jpg/jpgw坐标文件的格式
- TIFF坐标的转换,生成新的图像
- java读取tiff格式图片信息的方式。
- Goole Map API V3动态加载数据库中的坐标信息并添加标记(ASP.NET)
- 用GPicSync软件为照片添加拍摄地点的坐标信息
- 添加一个frame 坐标
- 处理tiff格式dem数据的方法——输出xyz坐标
- OnMouseHover事件获取坐标信息
- 串口GPS显示坐标信息
- JAVA零碎要点008---tomcat启动的时候报错了严重: End event threw exception java.lang.reflect.InvocationTargetExcepti
- (一)线性模型
- Dijkstra 算法最短路模板
- Picasso使用学习(二)
- 两个日期之间的日历
- TIFF添加坐标信息
- 公众号用户发送消息后台PHP回复没有反应的解决办法
- bkdr hash
- Spring如何为bean注入null值
- Linux google host配置
- 【LeetCode】236. Lowest Common Ancestor of a Binary Tree
- 分组密码模式的总结
- MySQL自带数据库
- 轮播图组件