Skalowanie obrazka

Witam! Potrzebuje funkcji, która skalowałaby mi obrazek (wczytuje z pliku, skaluje, zapisuje). Próbowałem już z GDI+, ale przykłady z Internetu mi nie działają, a i nie udało mi się ich przerobić tak by działały (jak już kompilator przestaje wyrzucać błędy, to albo aplikacja się wysypuje, albo nic nie robi…). Używam Visual Studio 2008 i myślę, że po prostu rozwiązania stosowane w przykładach są z nim “niekompatybilne” ^^. Nie chcę też używać jakiś dużych bibliotek w stylu ImageMagick. Z góry dzięki.

Edit:

Zapomniałem powiedzieć, że chodzi o C++.

.NET, jeśli nie to GDI lub GDI+. To są biblioteki dostępne standardowo(.NET Framework w Viście jest).

W MSDN(GDI+) jest tutorial i opis funkcji klasy Image(ciebie interesuje konstruktor, Save i GetThumbnailImage).

Wydaje mi się, że GDI+ będzie najodpowiedniejsze, ale mam z nim problem.

#include 

#include 


using namespace Gdiplus;


int main()

{

	Image image(L"c:\\test\\blah.png");

	return 0;

}

Przy takim kodzie, dostaję komunikat o nieobsługiwanym wyjątku (nie ważne czy podaję ścieżkę do istniejącego katalogu, czy nie). Może ktoś mi podpowie co robię nie tak…?

Zacznijmy od tego jaki to wyjątek. :wink:

Na początku dostaję coś takiego:

“An unhandled win32 exception occured in test.exe [0000]” (te cyfry za każdym razem są inne)

A po rozpoczęciu debugowania:

“Unhandled exception at 0x7c9100e8 in test.exe: 0xC0000005: Access violation reading location 0x00000010.”

Spróbuj jednak dać drugi niby domyślny parametr:

Image image(L"c:\\test\\blah.png",FALSE);

Niestety to nie pomaga. Ani true, ani false i tak wyjątek jest ten sam.

A czy na pewno masz 0brazek na “c:\test\blah.png” ?

Na twoim miejscu na początek spróbował bym dać jakiś standardowy bmp na np: “c:\test\blah.bmp” i jego spróbować otworzyć:

Image image(L"c:\test\blah.bmp",FALSE);

Z bmp też nie działa. Pliki są na pewno:

sv7c53ybs9fnh1qplq7s.png

Ścieżka też chyba jest prawidłowo podana…

Jak zawsze, kolejny bubel od M$.

Weź lepiej na Delphi się przesiądź, tam jeżeli napisano że ma działać to na 100% działa.

Albo DevCpp i QT, tez działa bez zarzutów.

Ta…

Zapomniałeś o GdiplusStartup i GdiplusShutdown. Jeśli nie używasz wskaźników(tak jak tutaj) to musisz zwalniać Image przed wywołaniem GdiplusShutdown(np. tworząc nowy zakres) bo poleci wyjątek.

Napisz to w C#, będziesz miał mniej problemów.

using System;

using System.Drawing;

using System.IO;


namespace ImageScaler

{

  class Program

  {

    static void Main(string[] args)

    {

      try

      {

        if (args.Length != 3) 

        {

          throw new Exception("Bad arguments.");

        }


        if (!File.Exists(args[0]))

        {

          throw new Exception("Source file does not exist.");

        }


        string[] size = args[1].ToLower().Split('x');

        int width, height;


        try

        {

          width = int.Parse(size[0]);

          height = int.Parse(size[1]);


          if (width <= 0 || height <= 0)

          {

            throw new Exception();

          }

        }

        catch { throw new Exception("Wrong size argument."); }


        Image src = new Bitmap(args[0]);

        Image dst = new Bitmap(width, height, src.PixelFormat);


        using (Graphics g = Graphics.FromImage(dst))

        {

          RectangleF srec = new RectangleF(0, 0, src.Size.Width - 1, src.Height - 1);

          RectangleF drec = new RectangleF(-0.5f, -0.5f, dst.Size.Width, dst.Height);


          g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

          g.DrawImage(src, drec, srec, GraphicsUnit.Pixel);

        }


        dst.Save(args[2]);

      }

      catch(Exception ex)

      {

        Console.WriteLine(ex.Message);

      }

    }

  }

}

Po skompilowaniu powyższego kodu, możesz go odpalić tak:

>ImageScaler src.png 800x600 dst.png