Home > OS >  Problem with saving PNM image on Windows in my app
Problem with saving PNM image on Windows in my app

Time:11-15

I am creating a photo editing app for my c# project. I need to support different image formats, but to begin with, I chose a very simple format - PNM. At the moment, I can open PNM images and change the color scheme, but strange things happen when saving. When saving the image on macOS, everything works fine, but after trying a similar action on Windows, I got a strange effect, the colors were read with a shift of 1 byte with each new opening after saving.

Here is an example of an image: example image

That’s what is happening after loading and re-opening it on Windows: damaged image

It is logical to assume that the problem is in the methods of saving the image. I first write the entire file header to the stream, and then write the color bytes one by one.

I can't figure out what exactly the problem is, because when debugging, the array of bytes being written contained nothing extra. Opening the image in the notepad before and after saving, I did not find any visible changes.

Here is my implementation of saving in a file:

public void SaveTo(Stream stream)
{
    _filter.WriteHeader(stream, _image);

    foreach (var (x, y) in _enumerationStrategy.Enumerate(Width, Height))
    {
        var triplet = _image[x, y];
        _filter.Write(stream, triplet, _converterProvider.Converter);
    }
}
public void WriteHeader(Stream stream, IBitmapImage image)
{
    var builder = new StringBuilder();

    builder.AppendLine("P6");
    builder.AppendLine($"{image.Width} {image.Height}");
    builder.AppendLine("255");

    var header = builder.ToString();
    var headerBytes = Encoding.UTF8.GetBytes(header);
    
    stream.Write(headerBytes, 0, headerBytes.Length);
}

I tried to create a header of image without a string builder, and I tried to write the header to the stream in different ways. Trying different encodings to convert bytes didn't work out too. The effect is the same...

CodePudding user response:

I guess your issue is caused by inconsistent line endings between operating systems. When you use AppendLine it adds a \n character after your string which is translated to binary differently, depending on the OS you running. I suggest you to write a line ending directly like so:

builder.Append((char)10);
  • Related