LIBTIFF存储代码,存图、拼图

首先准备几张图片

我要把这几张图片拼成一张大图,拼接效果如下所示:

继续往下看。

一 准备图片

 1     std::vector<std::string> fileNames;
 2     fileNames.push_back("./Scan-Compare/1.jpg");
 3     fileNames.push_back("./Scan-Compare/2.jpg");
 4     fileNames.push_back("./Scan-Compare/3.jpg");
 5     fileNames.push_back("./Scan-Compare/4.jpg");
 6     fileNames.push_back("./Scan-Compare/5.jpg");
 7     fileNames.push_back("./Scan-Compare/6.jpg");
 8     std::vector<cv::Mat> mats;
 9     CTileTiff tiff("D:/1.tiff");
10  
11     for (int i = 0; i < fileNames.size(); i++)
12     {
13         cv::Mat img = cv::imread(fileNames[i]);
14         cv::Mat dst;
15         resize(img, dst, Size(4096, 4096), 0.0, 0.0);
16         //cv::imshow("dst", dst);
17         cv::cvtColor(dst, dst, CV_BGR2RGB);
18         mats.push_back(dst);
19     }

二.设置TIFF的文件信息

1 bool CTileTiff::SetTileInfo(int nTileW, int nTileH, int nLayer,int nHeight,int nWidth)
2 {
3     m_nTileWidth = nTileW;
4     m_nTileHeight = nTileH;
5     m_nLayers = nLayer;
6     m_nWidth = nWidth;
7     m_nHeight = nHeight;
8 }

三.存储每一张图片

 1 bool CTileTiff::SaveImage(cv::Mat &img, const int nLeft, const int nTop,
 2     const int nRight, const int nBottom)
 3 {
 4     int nX = nLeft, nY = nTop;
 5  
 6     //int nWidth = nRight - nX, nHeight = nBottom - nY;
 7     const int nRows = img.rows / m_nTileHeight;
 8     const int nCols = img.cols / m_nTileWidth;
 9     cout << "nRows,nCols:" << nRows << "," << nCols << endl;
10  
11     const int nPitch = (nRight - nLeft) * 3;
12     const int nLayerID = 0;
13  
14     for (int i = 0; i < nRows; ++i)
15     {
16         const int nT = nY + i * m_nTileHeight;
17         const int nB = nT + m_nTileWidth;
18         for (int j = 0; j < nCols; ++j)
19         {
20             const int nL = nX + j * m_nTileWidth;
21             const int nR = nL + m_nTileWidth;
22             cout << nT << "," << nL  << endl;
23  
24             cv::Rect rect(j * m_nTileWidth, i * m_nTileHeight, m_nTileWidth, m_nTileHeight);
25  
26             cv::Mat roi = img(rect).clone();
27  
28  
29             bool bOk = saveTile(roi, nL, nT, nR, nB, nLayerID);
30             if (!bOk)
31             {
32                 continue;
33             }
34         }
35     }
36 //这里是为了下采样,按金字塔格式存储
37     int nSubW = nCols, nSubH = nRows;
38     int nSubLayer = nLayerID;
39     while (true)
40     {
41         nSubW /= 2;
42         nSubH /= 2;
43         nSubLayer++;
44         if (1 > nSubW || 1 > nSubH)
45         {
46             break;
47         }
48  
49         const int nScale = 1 << nSubLayer;
50         for (int i = 0; i < nSubH; ++i)
51         {
52             const int nT = nY + i * m_nTileWidth * nScale;
53             const int nB = nT + m_nTileHeight * nScale;
54             for (int j = 0; j < nSubW; ++j)
55             {
56                 const int nL = nX + j * m_nTileWidth * nScale;
57                 const int nR = nL + m_nTileWidth * nScale;
58        
59  
60  
61                 cv::Rect rect(nL - nX, nT - nY, m_nTileWidth * nScale, m_nTileHeight * nScale);
62  
63                 cv::Mat roi = img(rect).clone();
64  
65                 cv::Mat resized;
66  
67                 ResizeImg(roi.data,
68                     resized.data, m_nTileWidth * nScale, m_nTileHeight * nScale, 3, nPitch, m_nTileWidth, m_nTileHeight,
69                     3, m_nTileWidth*3);
70  
71                 
72                 bool bOk = saveTile(resized, nL, nT, nR, nB, nSubLayer);
73                 if (!bOk)
74                 {
75                     continue;
76                 }
77             }
78         }
79     }
80     
81  
82     return true;
83 }

四. 存储每一个tile

 1 bool CTileTiff::saveTile(cv::Mat& roi, const int nL, const int nT,const int nR, const int nB, const int nLayer)
 2 {
 3     if (roi.empty())
 4     {
 5         return false;
 6     }
 7     const int nWidth = nR - nL;
 8     const int nHeight = nB - nT;
 9     int nLength = 0;
10  
11     cout << nL << "," << nT << "," << nR << "," << nB << endl;
12  
13     try
14     {
15         TIFFSetDirectory(m_pFile, nLayer);
16         TIFFSetField(m_pFile, TIFFTAG_IMAGEWIDTH, m_nWidth/(nLayer+1));
17         TIFFSetField(m_pFile, TIFFTAG_IMAGELENGTH, m_nHeight/(nLayer + 1));
18         TIFFSetField(m_pFile, TIFFTAG_TILEWIDTH, m_nTileWidth);
19         TIFFSetField(m_pFile, TIFFTAG_TILELENGTH, m_nTileHeight);
20         TIFFSetField(m_pFile, TIFFTAG_SUBFILETYPE, FILETYPE_REDUCEDIMAGE);
21         TIFFSetField(m_pFile, TIFFTAG_BITSPERSAMPLE, 8);
22         TIFFSetField(m_pFile, TIFFTAG_SAMPLESPERPIXEL, 3);
23         TIFFSetField(m_pFile, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
24         TIFFSetField(m_pFile, TIFFTAG_COMPRESSION, COMPRESSION_JPEG);
25         TIFFSetField(m_pFile, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
26         int nJpegQuality = 60;
27         TIFFSetField(m_pFile, TIFFTAG_JPEGQUALITY, nJpegQuality);
28  
29         //根据需要设置分辨率
30         /*if (nLayer == 0)
31         {
32             float fPixelSize = 0.00068f;
33             int nScale = 20;
34             fPixelSize = fPixelSize * 100 / max(1, nScale);
35             TIFFSetField(m_pFile, TIFFTAG_XRESOLUTION, 1.0 / (fPixelSize / 10));
36             TIFFSetField(m_pFile, TIFFTAG_YRESOLUTION, 1.0 / (fPixelSize / 10));
37             TIFFSetField(m_pFile, TIFFTAG_RESOLUTIONUNIT, 3);
38         }*/
39  
40  
41         // save tile information
42         const int nTileRow = nT / m_nTileHeight;
43         const int nTileCol = nL / m_nTileWidth;
44         int tiffIndex = nTileRow * (m_nWidth / (nLayer+1)/m_nTileWidth) + nTileCol;
45         cout << "tiffIndex:" << tiffIndex << "," << nTileRow << "," << nTileCol << ","   << endl;
46  
47         TIFFWriteEncodedTile(m_pFile, tiffIndex, (void*)roi.data, m_nTileWidth * m_nTileHeight * 3);
48  
49         TIFFWriteDirectory(m_pFile);
50  
51         
52     }
53     catch (const std::exception& e)
54     {
55         //LOG_E("write tiff error:%s", e.what());
56     }
57  
58     return true;
59 }

五.简单的存储DEMO

 1     int nWidth = mats[0].cols;
 2     int nHeight = mats[0].rows;
 3     tiff.SetTileInfo(256, 256, 1, nHeight*2, nWidth*3);
 4     
 5     //第一行. 这样是为了demo 看起来容易理解,真正开发的时候你至少得用循环吧。。。
 6     tiff.SaveImage(mats[0], 0, 0, nWidth, nHeight);
 7     tiff.SaveImage(mats[1], nWidth, 0, nWidth * 2, nHeight);
 8     tiff.SaveImage(mats[2], nWidth*2, 0, nWidth * 3, nHeight);
 9     //第二行
10     tiff.SaveImage(mats[3], 0, nHeight, nWidth, nHeight*2);
11     tiff.SaveImage(mats[4], nWidth, nHeight, nWidth * 2, nHeight * 2);
12     tiff.SaveImage(mats[5], nWidth * 2, nHeight, nWidth * 3, nHeight * 3);
原文地址:https://www.cnblogs.com/ybqjymy/p/13704500.html