SetResolution ничего не делает при объединении изображений TIFF

1

Я пытался настроить разрешение для нового tiff, который создается из группы других tiff. Я хотел бы отказаться от разрешения до 100x100 точек на дюйм. Все с соединением работает правильно, но разрешение в финальном tiff всегда будет тем, что разрешение файлов, с которыми я соединяюсь (используются изображения 300x300 точек на дюйм). Я попытался использовать некоторые предложения (установить значение DPI для Tiff Image в С#) для получения/установки PropertyItems, но это тоже не удалось. Используя нижеприведенную технологию соединения, каков был бы правильный способ установить разрешение конечного изображения на 100x100 точек на дюйм?

Спасибо.

public byte[] JoinTiffImages(
        List<byte[]> images)
    {
        var fPage = FrameDimension.Page;

        var nearest =
            System.Drawing
                  .Drawing2D
                  .InterpolationMode
                  .NearestNeighbor;

        if (images.Count == 0)
        {
            throw new ImageConverterException(
                "Could not join an empty set of images.");
        }
        else if (images.Count == 1)
        {
            return images[0];
        }
        else
        {
            using (var ms = new MemoryStream())
            {
                using (var masterBitmap =
                    (Bitmap)DrawingImage.FromStream(
                        new MemoryStream(images[0])))
                {
                    //get the codec for tiff files
                    var info = GetTifCodecInfo();
                    var enc = Encoder.SaveFlag;
                    var ep = new EncoderParameters(2);

                    ep.Param[0] = new EncoderParameter(
                        enc,
                        (long)EncoderValue.MultiFrame);

                    ep.Param[1] = new EncoderParameter(
                        Encoder.Compression,
                        (long)TifCompression.ToEncoderValue());

                    masterBitmap.SetResolution(100.0f, 100.0f);
                    masterBitmap.Save(ms, info, ep);

                    //save the intermediate frames
                    ep.Param[0] = new EncoderParameter(
                        enc,
                        (long)EncoderValue.FrameDimensionPage);

                    for (int i = 1; i < images.Count; i++)
                    {
                        using (var nextImg = (Bitmap)DrawingImage.FromStream(
                            new MemoryStream(images[i])))
                        {
                            for (int x = 0;
                                    x < nextImg.GetFrameCount(fPage);
                                    x++)
                            {
                                nextImg.SetResolution(100.0f, 100.0f);
                                nextImg.SelectActiveFrame(fPage, x);

                                masterBitmap.SaveAdd(nextImg, ep);
                            }
                        }
                    }

                    ep.Param[0] =
                        new EncoderParameter(
                            enc,
                            (long)EncoderValue.Flush);

                    //close out the file.
                    masterBitmap.SaveAdd(ep);

                    return ms.ToArray();
                }
            }
        }
    }
  • 0
    Это может / не может быть связано с вашей проблемой, но вы выполняете большую работу, которую вы отбрасываете, когда создаете новый растровый файл с именем img , получаете из него объект Graphics, nextImg в нем nextImg , а затем просто сбрасываете его , Мне интересно, если вы намеревались добавить img в masterBitmap . Наряду с этим, вы пытались установить разрешение img и добавить его к мастеру, в отличие от добавления nextImg к мастеру.
  • 0
    Вам нужно установить разрешение перед тем, как нарисовать изображение, как для нарисованного, так и для принимающего изображения! Вы делаете это правильно для nextImg, но неправильно для masterBitmap.
Показать ещё 9 комментариев
Теги:
gdi+
tiff
resolution

2 ответа

1
Лучший ответ

Мне удалось решить мою проблему с некоторой помощью из комментариев. Эта функция будет обрабатывать изменение разрешения без изменения размера изображения.

public static byte[] JoinTiffImages(
    List<byte[]> images,
    float res)
{
    var fPage = FrameDimension.Page;

    var nearest =
        System.Drawing
                .Drawing2D
                .InterpolationMode
                .NearestNeighbor;

    if (images.Count == 0)
    {
        throw new Exception(
            "Could not join an empty set of images.");
    }
    else if (images.Count == 1)
    {
        return images[0];
    }
    else
    {
        var ms = new MemoryStream();

        //get the codec for tiff files
        var info = GetTifCodecInfo();
        var ep = new EncoderParameters(2);

        ep.Param[0] = new EncoderParameter(
            System.Drawing.Imaging.Encoder.SaveFlag,
            (long)EncoderValue.MultiFrame);

        ep.Param[1] = new EncoderParameter(
            System.Drawing.Imaging.Encoder.Compression,
            (long)EncoderValue.CompressionLZW);

        using (var masterImg =
            (Bitmap)System.Drawing.Image.FromStream(
                new MemoryStream(images[0])))
        {
            using (var resizedMaster =
                new Bitmap(
                    (int)(masterImg.Width *
                        (res /
                            masterImg.HorizontalResolution)),
                    (int)(masterImg.Height *
                        (res /
                            masterImg.VerticalResolution))))
            {
                resizedMaster.SetResolution(
                    res,
                    res);

                using (var gr = Graphics.FromImage(resizedMaster))
                {
                    gr.InterpolationMode = nearest;

                    gr.DrawImage(
                        masterImg,
                        new Rectangle(
                            0,
                            0,
                            resizedMaster.Width,
                            resizedMaster.Height),
                        0,
                        0,
                        masterImg.Width,
                        masterImg.Height,
                        GraphicsUnit.Pixel);
                }

                resizedMaster.Save(ms, info, ep);

                //save the intermediate frames
                ep.Param[0] = new EncoderParameter(
                    System.Drawing.Imaging.Encoder.SaveFlag,
                    (long)EncoderValue.FrameDimensionPage);

                for (int i = 1; i < images.Count; i++)
                {
                    using (var nextImg =
                        (Bitmap)System.Drawing.Image.FromStream(
                        new MemoryStream(images[i])))
                    {
                        for (int x = 0;
                            x < nextImg.GetFrameCount(fPage);
                            x++)
                        {
                            nextImg.SelectActiveFrame(fPage, x);

                            using (var resizedNext =
                                new Bitmap(
                                    (int)(nextImg.Width *
                                        (res /
                                            nextImg.HorizontalResolution)),
                                    (int)(nextImg.Height *
                                        (res /
                                            nextImg.VerticalResolution))))
                            {
                                resizedNext.SetResolution(
                                    res,
                                    res);

                                using (var gr =
                                    Graphics.FromImage(resizedNext))
                                {
                                    gr.InterpolationMode = nearest;
                                    gr.DrawImage(
                                        nextImg,
                                        new Rectangle(
                                            0,
                                            0,
                                            resizedNext.Width,
                                            resizedNext.Height),
                                        0,
                                        0,
                                        nextImg.Width,
                                        nextImg.Height,
                                        GraphicsUnit.Pixel);
                                }

                                resizedMaster.SaveAdd(resizedNext, ep);
                            }
                        }
                    }
                }

                ep.Param[0] =
                    new EncoderParameter(
                        System.Drawing.Imaging.Encoder.SaveFlag,
                        (long)EncoderValue.Flush);

                //close out the file.
                resizedMaster.SaveAdd(ep);
            }

            return ms.ToArray();
        }
    }
}

private static ImageCodecInfo GetTifCodecInfo()
{
    foreach (var ice in ImageCodecInfo.GetImageEncoders())
    {
        if (ice.MimeType == "image/tiff")
        {
            return ice;
        }
    }

    return null;
}
  • 0
    Я заметил, что вы также добавили поддержку для настройки каждого кадра исходных изображений. Хороший ответ.
1

Вот код, который создает многостраничный файл tif из списка изображений. Он устанавливает DPI как ведущему, так и всем частям в соответствии с входным параметром.

private void saveTiff_Click(List<Image> imgList, string saveName,  int dpi)
{
    //all kudos to : http://bobpowell.net/generating_multipage_tiffs.aspx

    foreach (Image img in imgList) ((Bitmap)img).SetResolution(dpi, dpi);

    System.Drawing.Imaging.Encoder enc = System.Drawing.Imaging.Encoder.SaveFlag;
    Bitmap master = new Bitmap(imgList[0]);
    master.SetResolution(dpi, dpi);
    ImageCodecInfo info = null;

    // lets hope we have an TIF encoder
    foreach (ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders())
        if (ice.MimeType == "image/tiff")  info = ice;

    // one parameter: MultiFrame
    EncoderParameters ep = new EncoderParameters(1);
    ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.MultiFrame);
    master.Save(saveName, info, ep);

    // one parameter: further frames
    ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.FrameDimensionPage);
    for (int i = 1; i < imgList.Count; i++)  master.SaveAdd(imgList[i], ep);

    // one parameter: flush
    ep.Param[0] = new EncoderParameter(enc, (long)EncoderValue.Flush);
    master.SaveAdd(ep);
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню