C#Image to Postscript最终偏离中心

时间:2016-11-15 19:31:53

标签: c# image postscript

我创建了一个可以用C#中的输入数据创建Postscript文件的库。但是,使用以下代码创建图像时,图像显示不正确。就像他们偏离中心一样。从左到右,您首先看到图像的右边缘,然后图像的左侧显示在图像的其余分配空间中。为了清楚起见,就像接受“hello”这个词,而不是显示“ohell”。

我正在使用以下C#代码创建一个List对象,该对象填充了直接输出到postscript文件的行。它看起来很标准我,虽然我注意到我必须编写的几个特点。由于某种原因,我的75宽度图像想要显示宽度为76像素,所以我添加了一个部分来添加一个像素。我不知道为什么会这样,而且我还没有做足够的测试,看看这一切都搞砸了。此外,通常情况下,我使用的图像矩阵具有负高度,后跟高度,但图像上下颠倒,所以我不得不交换它。

public virtual List<string> AddImage(Image img, int x, int y, int height, int width)
{
    string sDataSource;
    List<string> destinationList = new List<string>();
    int iImgWidth = img.Width;

    if (iImgWidth % 2 != 0)
    {
        iImgWidth += 1;
    }

    using (MemoryStream ms2 = new MemoryStream())
    {
       Bitmap bmp = (img as Bitmap).Clone(
           new Rectangle(0, 0, img.Width, img.Height), 
           PixelFormat.Format24bppRgb);
       bmp.Save(ms2, ImageFormat.Bmp);

       sDataSource = $"<{string.Join("", ms2.ToArray().Select(a => a.ToString("X2")))}>";
    }

    destinationList.Add($"{x} {y} translate");
    destinationList.Add($"{width} {height} scale");
    destinationList.Add(
        $"/DeviceRGB setcolorspace {{ << /ImageType 1 /Width {iImgWidth} /Height {img.Height} /ImageMatrix [{iImgWidth} 0 0 {img.Height} 0 {img.Height}] /BitsPerComponent 8 /Decode [0 1 0 1 0 1] ");
    destinationList.Add($"/DataSource {sDataSource} >> image }} exec ");

    return destinationList;
}

我的输出范围缩小到以下,但它仍然显示不正确。

%!PS-Adobe-3.1
0 649 translate
27 20 scale
/DeviceRGB setcolorspace { << /ImageType 1 /Width 76 /Height 56 /ImageMatrix [76 0 0 56 0 -56] /BitsPerComponent 8 /Decode [0 1 0 1 0 1] 
/DataSource <... (hex code)> >> image } exec 
showpage

有人能指出我正确的方向吗?几天来我一直在努力。

1 个答案:

答案 0 :(得分:0)

有两种可能的可能性,您在帖子中提到了它们,但如果没有原始图像数据,则无法判断您的假设是否正确。

首先,您已将图像颠倒了。在PostScript中,0,0是页面的左下角,增加y向上移动页面。图像通常从左上角开始,然后向下进行。

通常情况下,图像矩阵为[w 0 0 -h 0 h],而您似乎发出的是[w 0 0 h 0 -h]。当然这可能是正确的,如果不知道原始图像中样本的进展顺序,就不可能确定。

也可能是您的位图数据不正确,或者宽度错误(事实上您的宽度不是您预期的可疑),因此PostScript解释器以半个栅格宽度开始白色之后,它会绘制您所期望的图像的第一个(左侧)部分,直到它为整个栅格线读取(和渲染)足够的数据。

然后解释器移动到下一行图像并读取以下数据。然后,该数据由第一条栅格线的右手部分组成,后面是第二条线的左手部分。

等等。然后看来图像已被包裹。

这当然是推测,因为您还没有提供输入数据或最终PostScript程序的示例。我建议您在某处发布完整的示例输出并在此处链接到它。原始图像也可能有用,以便演示原始样本顺序。

[查看文件后]

好吧,从JPEG开始,我假设是原始文件,我看到十六进制字符串中的数据与解压缩的JPEG中的数据不匹配,也不是我所期望的。

鉴于大部分图像是白色的,我希望看到RGB三元组为0xFF 0xFF 0xFF,你的数据是:

424D0E0901000000000036000000280000009600000096000000010018000000000000000000232E0000232E00000000000000000000

我不知道那是什么,但我有理由相信它不是原始图像数据的一部分。看起来你的十六进制字符串是135710字节。现在,150 * 3字节的宽度(对于RGB = 450 * 150的高度导致预期数据为67,500字节* 2表示十六进制表示意味着您的数据应该是135000字节。所以它看起来像你的字符串&#39;可能&#39;其中有大约710个字节,或者118个RGB三元组太多。我可能已经搞砸了一些算法,但结果是你的字符串中的第一个&#39; FF&#39;这是可疑的: - )

我不会说C#所以我无法查看你的代码(实际上我甚至无法从实际代码所在的SourceForge项目中找到答案)。然而,在我看来你解决JPEG或打开输出文件等问题。删除数据流开头的奇怪内容并不能解决问题,但后来我不知道多少是无关的......

考虑到这个问题的本质,我认为我要做的第一件事是使用其他工具来提取图像数据(只是RGB三元组)。然后让我自己的代码写出相同的数据,理想情况下这些数据应该是相同的,但JPEG去量化可能会有细微差别。但是数据长度应该至少相同,内容应该非常相似。

有一些奇怪的蓝色&#39;出现在图像边缘的像素,我怀疑你在这里应用的解码存在问题。看着原版,我无法看到效果的来源,原作中没有垂直线,我可以看到。

顺便提一下,您应该知道某些PostScript实现对字符串长度限制为64KB,并且您的字符串已超过该限制。因此,您的文件将无法使用Adobe Acrobat Distiller或任何其他Adobe PostScript解释程序运行。如果你想创建更大的图像,你将不得不改变你的方法。