Coldfusion 2018 无 SOF 段多页 TIFF 错误



我有一个新的CF18服务器,我在读取和转换一些在以前的CF11服务器上可读的旧图像时遇到一些错误。仅供参考,GetReadableImageFormats 结果为"BMP,GIF,JPEG,JPEG 2000,JPEG2000,JPG,PNG,PNM,RAW,TIF,TIFF,WBMP">

通常我将文件作为二进制文件读取并将其放入内存中进行操作

<cffile action="readBinary" file="#file_location#" variable="binImage" />
<cfimage action="read" source="#binImage#" name="objImage" isbase64="no"> 

这现在会导致错误: "尝试读取图像时发生异常。流中没有 SOF 分段">

使用 action="read" 读取文件并转储左侧(binImage, 999( 结果: "...2015:10:07 17:46:58 Kofax 标准多页 TIFF 存储过滤器 v3.03.000,...">

然后我尝试使用以下方法将其读取到java中:

<cfset tifFileName="#file_location#">
<cfscript>
ss = createObject("Java","com.sun.media.jai.codec.FileSeekableStream").init(tifFileName);
//create JAI ImageDecoder
decoder = createObject("Java","com.sun.media.jai.codec.ImageCodec").createImageDecoder("tiff", ss, JavaCast("null",""));
</cfscript>

这会产生一个错误: "不支持解码旧式 JPEG-in-TIFF 数据。">

我发现这个... 不支持解码旧式 JPEG 中的 TIFF 数据

你认为使用十二只猴子ImageIO是解决我的问题的最佳途径吗?

更新:基于存在无效标记的建议0xFF9E我尝试了以下内容:

<cffile action="readBinary" file="#file_location#" variable="binImage" />
<cfset hexEncoding = binaryEncode(binImage, "hex")>
<cfset new_hexEncoding = replaceNoCase(hexEncoding, 'FF9E', 'FFE9', 'ALL')>
<cfset binImage = binaryDecode(new_hexEncoding, "hex")>

isImage(binImage( 返回"NO",并且"流中没有 SOF 段"错误仍然存在。我遍历十六进制编码,找到了FF9E字符串23x。我从未编辑过原始图像代码,所以我不确定我的替换是否正确。

编辑:在这一点上,我相当确定我的搜索和替换十六进制编码,"FF9E","FFE9"逻辑是有缺陷的。 二进制编码的 binImage 中没有发生0xff9e。

这让我发疯了。我尝试了我能找到的一切,除了安装额外的 JAVA 库或通过其他可执行文件路由它来进行转换。就我而言,TIFF中只有一个JPEG,所以我写了一些东西,从TIFF中获取JPEG的二进制数据(不考虑页面(并提供服务。一旦你有了JPEG的二进制文件,你就可以把它写到一个文件中,对它进行转换,甚至直接把它流式传输到浏览器。 未来需要这个的人来了。我写它不是为了做页面或检测它是什么样的 tiff,因为对于我的使用,我已经知道所有这些。这些东西是.bin文件,但它们都是相同的单页 jpeg 格式,我需要一种方法以浏览器不讨厌的格式快速提供它们。这运行得足够快,可以即时提供。有没有更好的方法?可能,但这有效,自包含,复制和粘贴,并且对任何需要编辑它的人都完全有意义。

<cfscript>
strFileName = "test.tiff";
blnOutputImageToBrowser = true;
blnSaveToFile = true;
strSaveFile = GetDirectoryFromPath(GetCurrentTemplatePath())&"test.jpg"
imgByteArray = FileReadBinary(strFileName);
//Convert to HEX String
hexString = binaryEncode(imgByteArray,"hex"); //Convert binary to HEX String, so we can pattern search it
//Set HEX Length
hexLength = arraylen(imgByteArray);
//Find Start of JPG Data in HEX String
jpegStartHEX = find("FFD8FF",hexString);
jpegStartBIN = (jpegStartHEX-1)/2; //-1 because CF arrays start on 1 and everyone else starts on 1. /2 because the HEX string positions are double the byte array positions
objByteBuffer = CreateObject("java","java.nio.ByteBuffer"); //Init JAVA byte buffer class for us to use later (this makes it go faster than trying to convert the hex string back to binary)
//Find Stop of JPG Data
jpegStopHEX = 0;
jpegStopBIN = 0;
intSearchIDX = jpegStartHEX+6; //Might as well start after the JPEG start block
blnStop = false;
while (intSearchIDX < len(hexString) && jpegStopHEX == 0 && !blnStop) {
newIDX = find("FFD9",hexString,intSearchIDX);
if (newIDX == 0) {
blnStop=true;
}
else {
if (newIDX%2 == 0) { //bad search try again (due to indexing in CF starting on 1 instead of 0, the even numbers are in between hex code [they are pairs like 00 and FF])
intSearchIDX = newIDX+1;
}
else { //Found ya
jpegStopHEX = newIDX;
blnStop=true;
}
}
}
jpegStopBIN = (jpegStopHEX-1)/2; //-1 because CF arrays start on 1 and everyone else starts on 1. /2 because the HEX string positions are double the byte array positions
//Dump JPG Binary into ByteArray from the start and stop positions we discovered
jpegLengthBIN = jpegStopBIN+2-jpegStartBIN;
objBufferImage = objByteBuffer.Allocate(JavaCast( "int", jpegLengthBIN ));
objBufferImage.Put(imgByteArray,JavaCast( "int", jpegStartBIN ),JavaCast( "int", jpegLengthBIN ));
if (blnSaveToFile) { //Dump byte array into test file
fileWrite(strSaveFile,objBufferImage.Array());
}
if (blnOutputImageToBrowser) {
img = ImageNew( objBufferImage.Array() );
ImageResize(img,"1200","","highestPerformance"); //Because we might as well show an example of resizing
outputImage(toBinary(toBase64(img))); //You could skip loading the byte array as an image object and just plop the binary in directly if you don't need to manipulate it any
}
</cfscript>
<cffunction name="outputImage" returntype="void">
<cfargument name="binInput" type="binary">
<cfcontent variable="#binInput#" type="image/png" reset="true" />
<cfreturn>
</cffunction>

最新更新