2008. március 26., szerda

Image objektum fájlból: hogyan és hogyan ne....

A .NET Framework System.Drawing névterében levő Image objektum nagyon megkönnyíti képekkel történő alapvető műveletek végzését. Amennyiben nem mi állítjuk elő a képet, hanem a fájlrendszerből kell felolvasni, akkor erre több módszer is létezik, de nem minden esetben megfelelő a legkézenfekvőbb megoldás.

Készítettem egy móricka osztályt a szemléltetéshez. A célom, hogy a képet egy másik könyvtárba mozgassam vagy átnevezzem, előtte és utána meg ezt-azt csinálgassak vele, valahogy így:
class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
ImageLoader loader = new ImageLoader();
loader.ImagePath = args[0];

//Load image
...
...

//do something terrible
...
...
loader.MoveImage(args[1]);
...
...
//do something terrible
}
else
Console.WriteLine("Add meg a forrast es a celt");
}
}

Csinálok is gyorsan egy osztályt, a megfelelő metódusokkal és természetesen a szükséges egységteszttel.



///
/// Minta az Image objektum létrehozására fájlból.
///

class ImageLoader
{
...
...

///

/// Kép felolvasása FromFile metódussal
///

public void SetImageWithFromFile()
{
ImageToLoad = Image.FromFile(ImagePath);
}

...
...
public void MoveImage(string destination)
{
File.Move(ImagePath, destination);
ImagePath = destination;
}
}

[TestFixture]
public class ImageLoaderTest
{
string originalpath;
string testpath;
...
...

[SetUp]
public void CreateTestData()
{
...
...
}

///
/// Az átnevezés tesztelése FromFile metódussal
///

[Test]
public void FromFileTest()
{
ImageLoader loader = new ImageLoader();
loader.ImagePath = originalpath;
loader.SetImageWithFromFile();
loader.MoveImage(testpath);

Assert.That(File.Exists(testpath) && (!File.Exists(originalpath)));
}

[TearDown]
public void DeleteTestData()
{
...
...
}

No lássuk mi történik...

Azt a hétlövetű kukoricacsövit neki! Hát ez bizony elesett....
Aszongya:

TestCase 'ImageLoader.ImageLoaderTest.FromFileTest'
failed: System.IO.IOException : A folyamat nem éri el a fájlt, mert már másik folyamat használja.

Hm. Mit is mond a help erről a metódusról?
Aszongya:

The file remains locked until the Image is disposed.

Jaj-jaj-jaj. Most mit tegyek, hisz nem akarom dispose-olni, mert nekem az még kell és különben is...
Ha memóriában dolgozék akár jó is lehetne a dolog...



class ImageLoader
{
...
...

///
/// Kép felolvasása stream segítségével.
///

public void SetImageWithStream()
{

byte[] imagebytes = File.ReadAllBytes(ImagePath);
MemoryStream ms = new MemoryStream(imagebytes);
ImageToLoad = Image.FromStream(ms);
}

...
...
}

[TestFixture]
public class ImageLoaderTest
{
...
...

[SetUp]
public void CreateTestData()
{
...
...
}

///
/// Átnevezés FromStream metódussal
///

[Test]
public void FromStreamTest()
{
ImageLoader loader = new ImageLoader();
loader.ImagePath = originalpath;
loader.SetImageWithStream();
loader.MoveImage(testpath);

Assert.That(File.Exists(testpath) && (!File.Exists(originalpath)));
}

[TearDown]
public void DeleteTestData()
{
...
...
}

Mit is mond a Saga a ReadAllBytes -ról?
Opens a binary file, reads the contents of the file into a byte array, and then closes the file.
Na akkor most, nincs nyitott fájlom, van viszont egy Image objectem amivel azt csinálok amit csak akarok, a memorystreamtől pedig ráérek megszabadulni, amikor mindent befejeztem vagy rábízom a szemétgyűjtőre.

Nincsenek megjegyzések: