TIFF文件切割_tif文件分割

TIFF文件切割_tif文件分割TIFF文件由于可以存储多种形式的数据类型,也可以存储大量的数据,故其体积比较大,如果我们想截取其中的一部分图片数据,如下图:截取如下图部分:保存之后同样还是一个TIFF图片。1.自己定义了一个类实现头文件:#pragmaonce#include#include”tiflib.h”#include#include

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

TIFF文件由于可以存储多种形式的数据类型,也可以存储大量的数据,故其体积比较大,如果我们想截取其中的一部分图片数据,如下图:
这里写图片描述
截取如下图部分:
这里写图片描述
保存之后同样还是一个TIFF图片。
1.自己定义了一个类实现
头文件:

#pragma once
#include <Windows.h>
#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 set_cut_rect( int x1 , int y1 , int x2 , int y2 );
    int arrangement();//0 - tile 1 - line
    bool analysis( char* ret_error );  //分析tiff是否可以进行转换 true - 可以 false - 不可以 
    int save_to_trans( const char* new_path = NULL , const char* new_name = NULL );

    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 );
    void coord_box( geoRECT geo_rect );
private:
    string new_tiff_name( string save_dir );
    void write_file_header();

    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_tile_tag();
    int cts_new_tag_list();

    void print_tag_info_list();
    void write_tag_list();
    void modify_strip_offset();

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

    deInfo* delete_coord_tag( );
    void write_img_data();
    void write_img_data2();

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;             //标签的数量

    TIFF_UINT32_T _strip_offset_pos;   //TAG StripOffset的文件偏移位置

    int _tiff_w_src , _tiff_h_src ;
    int _tiff_start_x;
    int _tiff_start_y;
    int _tiff_end_x;
    int _tiff_end_y;

    int _coord_tag_num; //包含坐标信息的TAG的数量

    TIFF_UINT64_T pixel_scale[3];//像元比例
    TIFF_UINT64_T tie_point[6];//控制点坐标对

    geoRECT _geo_rect;
    deInfo _new_tie_tag ;
};

Jetbrains全家桶1年46,售后保障稳定

.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;
_tiff_w_src = _tiff_src->tif_width; 
_tiff_h_src = _tiff_src->tif_height;
_coord_tag_num = 0 ;
return  ret;
}
void tiffTrans::set_cut_rect( int x1 , int y1 , int x2 , int y2 )
{
_tiff_start_x = x1;
_tiff_start_y = y1;
_tiff_end_x = x2;
_tiff_end_y = y2;
_tiff_src->tif_width = _tiff_end_x - _tiff_start_x;
_tiff_src->tif_height = _tiff_end_y - _tiff_start_y;
geoRECT pixel_rect ;
pixel_rect.left = 0 ;
pixel_rect.top = 0 ;
pixel_rect.right = _tiff_w_src;
pixel_rect.botton = _tiff_h_src;
geo_coord( _tiff_src , pixel_rect , _geo_rect );
//cs_pixel_scale( scaleX , scaleY );
double new_start_x = _geo_rect.left + _tiff_src->geo_tiff.pixel_scale.scaleX * _tiff_start_x;
double new_start_y = _geo_rect.top - _tiff_src->geo_tiff.pixel_scale.scaleY * _tiff_start_y ;
cs_tie_point( new_start_x , new_start_y );
_new_tie_tag.de.tag = 33922;//GeoTagTiePoint
_new_tie_tag.de.type = 12;//double
_new_tie_tag.de.count = 6 ;
_new_tie_tag.de.offset = 0 ;
_new_tie_tag.data_source = 2;//内存数据
_new_tie_tag.mem_data = ( TIFF_UINT8_T* )tie_point;
}
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( string save_dir )
{
int pos = _src_name.rfind( '\\' );
string tiff_name = _src_name.substr( pos + 1 );
string dir = save_dir/*_src_name.substr( 0 , pos + 1 )*/;
string temp_name = "\\cut_";
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 );
}
if ( de_list[i].de.tag == 256 )
{
de_list[i].de.offset = _tiff_end_x - _tiff_start_x;
}
if ( de_list[i].de.tag == 257 )
{
de_list[i].de.offset = _tiff_end_y - _tiff_start_y;
}
//如果是 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_tile_tag()
{
deInfo* temp_de_list = new deInfo[ _de_num - 3 ];//tile 共4个标签
memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num - 3) );
int j = 0;
for ( int i = 0 ; i < _de_num ; i ++ )
{
if ( ( de_list[i].de.tag != 273 )&& //StripOffsets
( de_list[i].de.tag != 278 )&& //RowsPerStrip
( de_list[i].de.tag != 279 )//StripByteCounts
)
{
memcpy ( temp_de_list + j , de_list + i , sizeof(deInfo) );
j++;
}
}
delete[] de_list;
de_list = NULL;
de_list = temp_de_list;
_de_num -= 3 ;
return de_list;
}
int tiffTrans::cts_new_tag_list( )
{
de_list = delete_tile_tag();
//de_list = delete_coord_tag();
deInfo* temp_line = cts_line_tag();
deInfo* temp_de_list = new deInfo[ _de_num + 3 ];//tile 4个标签 line 只需要3个标签
memset( temp_de_list , 0 , sizeof(deInfo)*( _de_num + 3 ) );
int j = 0 , k = 0 ;
for ( int i = 0 ; i < _de_num ; i++ )
{
if ( de_list[i].de.tag == 33922 )//ModelTiepointTag
{
memcpy ( &de_list[i] , &_new_tie_tag , sizeof( deInfo )); 
}
if ( k < 3 )//line只有三个标签
{
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++;
}
}
delete[] de_list;
de_list = NULL;
de_list = temp_de_list;
_de_num += 3;
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()
{
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.count > 1 )//Strip offset
{
fseek( _line_tiff , 0 , SEEK_END );
_strip_offset_pos = ftell( _line_tiff );
}
//写入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_strip_offset()
{
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 width_bytes = _tiff_src->tif_width * _tiff_src->samples_per_pixel ;
for ( int i = 0 ; i < _tiff_src->tif_height ; i++ )
{
TIFF_UINT32_T height_start = current_size + i * width_bytes;
fwrite( &height_start , 1 , 4 , _line_tiff );
}
}
void tiffTrans::write_img_data()
{
fseek( _line_tiff , 0 , SEEK_END );
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()
{
fseek( _line_tiff , 0 , SEEK_END );
long theight = _tiff_h_src/*_tiff_src->tif_height */;
TIFF_UINT32_T* height_start = (TIFF_UINT32_T*) VirtualAlloc ( NULL , theight*sizeof(TIFF_UINT32_T) , MEM_COMMIT , PAGE_READWRITE );
_tiff_src->tif_width = _tiff_w_src; 
_tiff_src->tif_height = _tiff_h_src ;
int bits =  _tiff_src->bit_per_samples ;
if ( bits >= 24 )
{
if ( !_tiff_src->tile.is_tile )//瓦片数据
{
fresh_line_start( _tiff_src , height_start );
}
}
int len = ( _tiff_end_x - _tiff_start_x )* _tiff_src->samples_per_pixel ;
TIFF_UINT8_T* buf = new TIFF_UINT8_T[ len ];
memset( buf , 0 , len );
for ( int i = _tiff_start_y ; i < _tiff_end_y ; i++ )
{
/*fseek*/_fseeki64( _tile_tiff , ( height_start[i] + _tiff_start_x * _tiff_src->samples_per_pixel ) , SEEK_SET );
fread( buf ,1 , len , _tile_tiff );
fwrite( buf , 1 , len , _line_tiff );
}
delete[] buf;
buf = NULL ;
if ( height_start != NULL )
{
VirtualFree( height_start , 0 , MEM_RELEASE );
height_start = NULL;
}
}
int tiffTrans::save_to_trans( const char* new_path , const char* new_name )
{
string temp_path;
if (  strlen( new_path )!= 0 && strlen( new_name ) == 0 )
{
temp_path = new_tiff_name( new_path ) ;
}
else
{
temp_path = new_path ;
temp_path += "\\";
temp_path += new_name;
}
_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 );
return 0;
}
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;
}
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 );
}
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;
}

2.使用方法:

#include "tifftrans.h"
int main( int argc, char* argv[] )
{
if ( argc < 8 )
{
printf("error : 请输入正确的命令和参数!\n");
printf("D:\\xxx.tif 左:100 上:100 右:300 下:300 D:\\yyy new_name.tif\n");
return -1;
}
tiffTrans _tiff_trans;
_tiff_trans.open( argv[1] );
_tiff_trans.set_cut_rect( atoi(argv[2]) , atoi(argv[3]) , atoi(argv[4]) , atoi(argv[5]) );
_tiff_trans.save_to_trans( argv[6] , argv[7] ); 
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/226869.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • minipcie标准接口定义_minipcie接口都可以接什么

    minipcie标准接口定义_minipcie接口都可以接什么miniPCIe标准结构尺寸接口标准PCB封装

  • MySQL为什么用B+树,而不用B树?

    MySQL为什么用B+树,而不用B树?

  • 小程序商城订单支付界面(小程序)

    小程序商城订单支付界面(小程序)wxml在此:<!–pages/cart/cart.wxml–><!–当数据为空时–><viewclass=’noData’wx:if=”{{dataList.length==0}}”><viewclass=’noDataImg’><imagesrc=’/images/cart-nodata…

  • SpringMVC 执行流程

    SpringMVC 执行流程springMVC(javaweb开发框架)1、MVC三层架构:模型(service、dao)、视图(JSP等)、控制器(Controller)什么是mvc?*MVC是模型、视图、控制器的简写,是一种软件设计规范*是将业务逻辑、数据、显示分离的方法来组织代码*MVC主要的作用就是降低了控制器(Controller)和视图(View)之间的双向耦合度*MVC不是一种设计模式、MVC是一种架构模式。当然不同的MVC存在着差异Model(数据模型):提供要展示的数据。因此包含数据和

  • 批处理FOR 中的Delims和Tokens总结「建议收藏」

    批处理FOR 中的Delims和Tokens总结「建议收藏」本篇为《FOR入门与精通秘籍》的补充内容。由于《FOR入门与精通秘籍》是当初刚开始学FOR时一边学一边写的,思维难免受人家影响,思考的也不够全面,所以存在很多缺点,但又不想做过多修改,只好补写了这篇东西。       在For命令语句的参数F中,最难理解的就是Delims和Tokens两个选项,本文简单的做一个比较和总结。“For/f”常用来解析文本,读取字符串。分工上,delims负

    2022年10月12日
  • 变异系数法之matlab

    变异系数法之matlab1.简介2.算法原理2.1指标正向化2.2数据标准化2.3计算变异系数2.4计算权重以及得分3.实例分析3.1读取数据3.2指标正向化3.3数据标准化3.4计算变异系数3.5计算权重3.6计算得分完整代码

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号