2

なぜこれが難しいのかわかりませんが、LibTiff.Net 2.3 で有理数を正しく設定することができません...何年にもわたって、私は常に tiff タグ番号 282(XRESOLUTION ) および 283(YRESOLUTION)。しかし、LibTiff.Net ライブラリを使用すると、その結果を得ることは不可能に思えます。代わりに「419430400/2097152」のようなものが常に表示されます。この問題を解決する方法を知っている人はいますか?

私の質問に関するメモ:

これは libtiff ライブラリ (.Net 以前) であり、200/1 のようなものを説明する場合、最初の他のライブラリのように見えます。

TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32* ndir, TIFFDirEntry* dir, uint16 tag, uint32 count, float* value)
{
    static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
    uint32* m;
    float* na;
    uint32* nb;
    uint32 nc;
    int o;
    assert(sizeof(uint32)==4);
    m=_TIFFmalloc(count*2*sizeof(uint32));
    if (m==NULL)
    {
        TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
        return(0);
    }
    for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
    {
        if (*na<=0.0)
        {
            nb[0]=0;
            nb[1]=1;
        }
        else if (*na==(float)(uint32)(*na))
        {
            nb[0]=(uint32)(*na);
            nb[1]=1;
        }
        else if (*na<1.0)
        {
            nb[0]=(uint32)((*na)*0xFFFFFFFF);
            nb[1]=0xFFFFFFFF;
        }
        else
        {
            nb[0]=0xFFFFFFFF;
            nb[1]=(uint32)(0xFFFFFFFF/(*na));
        }
    }
    if (tif->tif_flags&TIFF_SWAB)
        TIFFSwabArrayOfLong(m,count*2);
    o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
    _TIFFfree(m);
    return(o);
}

これは新しい .Net バージョンです...

private bool writeRationalArray(ref TiffDirEntry dir, float[] v)
{
    int[] t = new int [2 * dir.tdir_count];
    for (int i = 0; i < dir.tdir_count; i++)
    {
        int sign = 1;
        float fv = v[i];
        if (fv < 0)
        {
            if (dir.tdir_type == TiffType.RATIONAL)
            {
                WarningExt(this, m_clientdata, m_name,
                "\"{0}\": Information lost writing value ({1:G}) as (unsigned) RATIONAL",
                FieldWithTag(dir.tdir_tag).Name, fv);
                fv = 0;
            }
            else
            {
                fv = -fv;
                sign = -1;
            }
        }

        int den = 1;
        if (fv > 0)
        {
            while (fv < (1L << (31 - 3)) && den < (1L << (31 - 3)))
            {
                fv *= 1 << 3;
                den *= 1 << 3;
            }
        }

        t[2 * i + 0] = (int)(sign * (fv + 0.5));
        t[2 * i + 1] = den;
    }

    return writeData(ref dir, t, 2 * dir.tdir_count);
}
4

2 に答える 2

6

これがあなたを助けてくれたら、必ず私に1UPをください. ありがとう!

わかりましたので、削減された分数を考慮してライブラリを編集することにしました。以下は、動作させるために .Net ライブラリで変更したコードです。そして、それはうまくいきます!

ボブロフスキーが次のリリースにこれを含めることを願っています。きっと私以外にも感謝してくれる人がいるはず!;)

ライブラリの編集方法が少しわからない場合は、ここで使用した手順をできるだけ詳しく説明します...

1)ここにあるライブラリ ソースをダウンロードします。

2) プロジェクトファイルを開きます。LibTiff.NET_NoSilverlight.slnソリューション ファイルを使用してプロジェクトを開きました。

3) LibTiffプロジェクト ノードを展開します。

4) [ Internals ]ノードを展開します。

5) Tiff_DirWrite.csクラス ファイルを見つけて開きます。

6) そのクラス ファイル内で、writeRationalArrayという関数を見つけました。これは次のように見えます...

/// <summary>
/// Setup a directory entry of an array of RATIONAL or SRATIONAL and
/// write the associated indirect values.
/// </summary>
private bool writeRationalArray(ref TiffDirEntry dir, float[] v)
{
    int[] t = new int [2 * dir.tdir_count];
    for (int i = 0; i < dir.tdir_count; i++)
    {
        int sign = 1;
        float fv = v[i];
        if (fv < 0)
        {
            if (dir.tdir_type == TiffType.RATIONAL)
            {
                WarningExt(this, m_clientdata, m_name,
                    "\"{0}\": Information lost writing value ({1:G}) as (unsigned) RATIONAL",
                    FieldWithTag(dir.tdir_tag).Name, fv);
                fv = 0;
            }
            else
            {
                fv = -fv;
                sign = -1;
            }
        }

        int den = 1;
        if (fv > 0)
        {
            while (fv < (1L << (31 - 3)) && den < (1L << (31 - 3)))
            {
                fv *= 1 << 3;
                den *= 1 << 3;
            }
        }

        t[2 * i + 0] = (int)(sign * (fv + 0.5));
        t[2 * i + 1] = den;
    }

    return writeData(ref dir, t, 2 * dir.tdir_count);
}

7) writeRationalArray関数を次のように編集します...

/// <summary>
/// Setup a directory entry of an array of RATIONAL or SRATIONAL and
/// write the associated indirect values.
/// </summary>
private bool writeRationalArray(ref TiffDirEntry dir, float[] v)
{
    int[] t = new int [2 * dir.tdir_count];
    for (int i = 0; i < dir.tdir_count; i++)
    {
        int sign = 1;
        float fv = v[i];
        if (fv < 0)
        {
            if (dir.tdir_type == TiffType.RATIONAL)
            {
                WarningExt(this, m_clientdata, m_name,
                    "\"{0}\": Information lost writing value ({1:G}) as (unsigned) RATIONAL",
                    FieldWithTag(dir.tdir_tag).Name, fv);
                fv = 0;
            }
            else
            {
                fv = -fv;
                sign = -1;
            }
        }

        int den = 1;
        if (fv > 0)
        {
            while (fv < (1L << (31 - 3)) && den < (1L << (31 - 3)))
            {
                fv *= 1 << 3;
                den *= 1 << 3;
            }
        }

        t[2 * i + 0] = (int)(sign * (fv + 0.5));
        t[2 * i + 1] = den;

        //Reduce the fraction
        int a = t[2 * i + 0];
        int b = t[2 * i + 1];
        while (b > 0) { int rem = a % b; a = b; b = rem; }
        for (int ind = 0; ind < 2; ind++) { t[2 * i + ind] /= a; }
    }

    return writeData(ref dir, t, 2 * dir.tdir_count);
}

最後に端数を減らすために 3 行のコードを追加しただけです。

于 2012-06-26T21:25:19.793 に答える
4

LibTiff.Netを使用する場合、次のような有理値を設定する必要があります。

image.SetField(TiffTag.XRESOLUTION, 150.0);
image.SetField(TiffTag.YRESOLUTION, 150.0);

ライブラリは、TIFFに整数値(被除数と除数)のペアとして有理数を書き込みます。あなたはそれでそれを助ける必要はありません。

于 2012-06-25T18:08:29.253 に答える