// For now, we only export in uncompressed ARGB32 format. If someone requests this functionality, // we can always add more through an export dialog. public void Export(Document document, string fileName) { ImageSurface surf = document.GetFlattenedImage (); // Assumes the surface is in ARGB32 format BinaryWriter writer = new BinaryWriter (new FileStream (fileName, FileMode.Create, FileAccess.Write)); try { TgaHeader header = new TgaHeader(); header.idLength = (byte) (ImageIdField.Length + 1); header.cmapType = 0; header.imageType = 2; // uncompressed RGB header.cmapIndex = 0; header.cmapLength = 0; header.cmapEntrySize = 0; header.xOrigin = 0; header.yOrigin = 0; header.imageWidth = (ushort) surf.Width; header.imageHeight = (ushort) surf.Height; header.pixelDepth = 32; header.imageDesc = 8; // 32-bit, lower-left origin, which is weird but hey... header.WriteTo (writer); writer.Write(ImageIdField); byte[] data = surf.Data; // It just so happens that the Cairo ARGB32 internal representation matches // the TGA format, except vertically-flipped. In little-endian, of course. for (int y = surf.Height - 1; y >= 0; y--) writer.Write (data, surf.Stride * y, surf.Stride); } finally { (surf as IDisposable).Dispose (); writer.Close (); } }
private void HandlePintaCoreActionsImageAutoCropActivated(object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit(); using (var image = doc.GetFlattenedImage()) { Gdk.Rectangle rect = image.GetBounds(); Cairo.Color border_color = image.GetPixel(0, 0); // Top down. for (int y = 0; y < image.Height; ++y) { if (!IsConstantRow(image, border_color, y)) { break; } ++rect.Y; --rect.Height; } // Bottom up. for (int y = rect.Bottom; y >= rect.Top; --y) { if (!IsConstantRow(image, border_color, y)) { break; } --rect.Height; } // Left side. for (int x = 0; x < image.Width; ++x) { if (!IsConstantColumn(image, border_color, rect, x)) { break; } ++rect.X; --rect.Width; } // Right side. for (int x = rect.Right; x >= rect.Left; --x) { if (!IsConstantColumn(image, border_color, rect, x)) { break; } --rect.Width; } // Ignore the current selection when auto-cropping. CropImageToRectangle(doc, rect, /*selection*/ null); } }
// For now, we only export in uncompressed ARGB32 format. If someone requests this functionality, // we can always add more through an export dialog. public void Export(Document document, string fileName) { ImageSurface surf = document.GetFlattenedImage(); // Assumes the surface is in ARGB32 format BinaryWriter writer = new BinaryWriter(new FileStream(fileName, FileMode.Create, FileAccess.Write)); try { TgaHeader header = new TgaHeader(); header.idLength = 0; header.cmapType = 0; header.imageType = 2; // uncompressed RGB header.cmapIndex = 0; header.cmapLength = 0; header.cmapEntrySize = 0; header.xOrigin = 0; header.yOrigin = 0; header.imageWidth = (ushort)surf.Width; header.imageHeight = (ushort)surf.Height; header.pixelDepth = 32; header.imageDesc = 8; // 32-bit, lower-left origin, which is weird but hey... header.WriteTo(writer); byte[] data = surf.Data; // It just so happens that the Cairo ARGB32 internal representation matches // the TGA format, except vertically-flipped. In little-endian, of course. for (int y = surf.Height - 1; y >= 0; y--) { writer.Write(data, surf.Stride * y, surf.Stride); } } finally { (surf as IDisposable).Dispose(); writer.Close(); } }
public void Export(Document document, string fileName) { Cairo.ImageSurface surf = document.GetFlattenedImage (); Pixbuf pb = surf.ToPixbuf (); DoSave(pb, fileName, filetype); (pb as IDisposable).Dispose (); (surf as IDisposable).Dispose (); }
public void Export(Document document, string fileName, Gtk.Window parent) { Cairo.ImageSurface surf = document.GetFlattenedImage(); Pixbuf pb = surf.ToPixbuf(); DoSave(pb, fileName, filetype, parent); (pb as IDisposable).Dispose(); (surf as IDisposable).Dispose(); }
public void Export(Document document, string fileName, Gtk.Window parent) { ZipOutputStream stream = new ZipOutputStream(new FileStream(fileName, FileMode.Create)) { UseZip64 = UseZip64.Off // For backwards compatibility with older versions. }; ZipEntry mimetype = new ZipEntry("mimetype"); mimetype.CompressionMethod = CompressionMethod.Stored; stream.PutNextEntry(mimetype); byte[] databytes = System.Text.Encoding.ASCII.GetBytes("image/openraster"); stream.Write(databytes, 0, databytes.Length); for (int i = 0; i < document.Layers.UserLayers.Count; i++) { using Pixbuf pb = document.Layers.UserLayers[i].Surface.ToPixbuf(); byte[] buf = pb.SaveToBuffer("png"); stream.PutNextEntry(new ZipEntry("data/layer" + i.ToString() + ".png")); stream.Write(buf, 0, buf.Length); } stream.PutNextEntry(new ZipEntry("stack.xml")); databytes = GetLayerXmlData(document.Layers.UserLayers); stream.Write(databytes, 0, databytes.Length); using ImageSurface flattened = document.GetFlattenedImage(); using Pixbuf flattenedPb = flattened.ToPixbuf(); // Add merged image. stream.PutNextEntry(new ZipEntry("mergedimage.png")); databytes = flattenedPb.SaveToBuffer("png"); stream.Write(databytes, 0, databytes.Length); // Add thumbnail. Size newSize = GetThumbDimensions(flattenedPb.Width, flattenedPb.Height); using Pixbuf thumb = flattenedPb.ScaleSimple(newSize.Width, newSize.Height, InterpType.Bilinear); stream.PutNextEntry(new ZipEntry("Thumbnails/thumbnail.png")); databytes = thumb.SaveToBuffer("png"); stream.Write(databytes, 0, databytes.Length); stream.Close(); }
public void Export(Document document, string fileName) { ZipOutputStream stream = new ZipOutputStream(new FileStream(fileName, FileMode.Create)); ZipEntry mimetype = new ZipEntry("mimetype"); mimetype.CompressionMethod = CompressionMethod.Stored; stream.PutNextEntry(mimetype); byte[] databytes = System.Text.Encoding.ASCII.GetBytes("image/openraster"); stream.Write(databytes, 0, databytes.Length); for (int i = 0; i < document.Layers.Count; i++) { Pixbuf pb = document.Layers[i].Surface.ToPixbuf(); byte[] buf = pb.SaveToBuffer("png"); (pb as IDisposable).Dispose(); stream.PutNextEntry(new ZipEntry("data/layer" + i.ToString() + ".png")); stream.Write(buf, 0, buf.Length); } stream.PutNextEntry(new ZipEntry("stack.xml")); databytes = GetLayerXmlData(document.Layers); stream.Write(databytes, 0, databytes.Length); ImageSurface flattened = document.GetFlattenedImage(); Pixbuf flattenedPb = flattened.ToPixbuf(); Size newSize = GetThumbDimensions(flattenedPb.Width, flattenedPb.Height); Pixbuf thumb = flattenedPb.ScaleSimple(newSize.Width, newSize.Height, InterpType.Bilinear); stream.PutNextEntry(new ZipEntry("Thumbnails/thumbnail.png")); databytes = thumb.SaveToBuffer("png"); stream.Write(databytes, 0, databytes.Length); (flattened as IDisposable).Dispose(); (flattenedPb as IDisposable).Dispose(); (thumb as IDisposable).Dispose(); stream.Close(); }
public void Export(Document document, string fileName) { ZipOutputStream stream = new ZipOutputStream (new FileStream (fileName, FileMode.Create)); ZipEntry mimetype = new ZipEntry ("mimetype"); mimetype.CompressionMethod = CompressionMethod.Stored; stream.PutNextEntry (mimetype); byte[] databytes = System.Text.Encoding.ASCII.GetBytes ("image/openraster"); stream.Write (databytes, 0, databytes.Length); for (int i = 0; i < document.UserLayers.Count; i++) { Pixbuf pb = document.UserLayers[i].Surface.ToPixbuf (); byte[] buf = pb.SaveToBuffer ("png"); (pb as IDisposable).Dispose (); stream.PutNextEntry (new ZipEntry ("data/layer" + i.ToString () + ".png")); stream.Write (buf, 0, buf.Length); } stream.PutNextEntry (new ZipEntry ("stack.xml")); databytes = GetLayerXmlData (document.UserLayers); stream.Write (databytes, 0, databytes.Length); ImageSurface flattened = document.GetFlattenedImage (); Pixbuf flattenedPb = flattened.ToPixbuf (); Size newSize = GetThumbDimensions (flattenedPb.Width, flattenedPb.Height); Pixbuf thumb = flattenedPb.ScaleSimple (newSize.Width, newSize.Height, InterpType.Bilinear); stream.PutNextEntry (new ZipEntry ("Thumbnails/thumbnail.png")); databytes = thumb.SaveToBuffer ("png"); stream.Write (databytes, 0, databytes.Length); (flattened as IDisposable).Dispose(); (flattenedPb as IDisposable).Dispose(); (thumb as IDisposable).Dispose(); stream.Close (); }
private void HandlePintaCoreActionsImageAutoCropActivated (object sender, EventArgs e) { Document doc = PintaCore.Workspace.ActiveDocument; PintaCore.Tools.Commit (); using (var image = doc.GetFlattenedImage ()) { Gdk.Rectangle rect = image.GetBounds (); Cairo.Color borderColor = image.GetPixel (0, 0); bool cropSide = true; int depth = -1; //From the top down while (cropSide) { depth++; for (int i = 0; i < image.Width; i++) { if (!borderColor.Equals(image.GetPixel (i, depth))) { cropSide = false; break; } } //Check if the image is blank/mono-coloured, only need to do it on this scan if (depth == image.Height) return; } rect = new Gdk.Rectangle (rect.X, rect.Y + depth, rect.Width, rect.Height - depth); depth = image.Height; cropSide = true; //From the bottom up while (cropSide) { depth--; for (int i = 0; i < image.Width; i++) { if (!borderColor.Equals(image.GetPixel (i, depth))) { cropSide = false; break; } } } rect = new Gdk.Rectangle (rect.X, rect.Y, rect.Width, depth - rect.Y); depth = 0; cropSide = true; //From left to right while (cropSide) { depth++; for (int i = 0; i < image.Height; i++) { if (!borderColor.Equals(image.GetPixel (depth, i))) { cropSide = false; break; } } } rect = new Gdk.Rectangle (rect.X + depth, rect.Y, rect.Width - depth, rect.Height); depth = image.Width; cropSide = true; //From right to left while (cropSide) { depth--; for (int i = 0; i < image.Height; i++) { if (!borderColor.Equals(image.GetPixel (depth, i))) { cropSide = false; break; } } } rect = new Gdk.Rectangle (rect.X, rect.Y, depth - rect.X, rect.Height); // Ignore the current selection when auto-cropping. CropImageToRectangle (doc, rect, /*selection*/ null); } }
public unsafe void Export(Document document, string fileName, Window parent) { int w = 64, h = 64; //Default value to configure, pixels per block string chars = DefaultCharacters.AsciiChars; //Get the selection from config ASCIIOptionsDialog dialog = new ASCIIOptionsDialog (w, h); try { dialog.WindowPosition = Gtk.WindowPosition.CenterOnParent; int response = dialog.Run (); if (response == (int)Gtk.ResponseType.Ok) { w = dialog.ExportImageWidth; h = dialog.ExportImageHeight; chars = dialog.ExportImageChars; } else { return; } } finally { dialog.Destroy (); } Cairo.ImageSurface surface = document.GetFlattenedImage (); int W = surface.Width, H = surface.Height; // Special case where 1 cell corresponds directly to 1 pixel // Written separately for performance if (h == 1 && w == 1) { StreamWriter writer = new StreamWriter(fileName); for (int y = 0; y < H; y++) { ColorBgra* current = surface.GetRowAddressUnchecked(y); for (int x = 0; x < W; x++) { int pos = (int)((1 - current->GetIntensity()) * chars.Length); char c = chars[pos == chars.Length ? pos - 1 : pos]; writer.Write(c); current++; } if (y != H - 1) { writer.WriteLine(); } } writer.Flush(); } else { double[,] totals = new double[W / w, H / h]; for (int y = 0; y < H / h * h; y++) { ColorBgra* current = surface.GetRowAddressUnchecked(y); for (int x = 0; x < W / w * w; x++) { totals[x / w, y / h] += 1 - current->GetIntensity(); current++; } } int ppc = w * h; StreamWriter writer = new StreamWriter(fileName); for (int y = 0; y < H / h; y++) { for (int x = 0; x < W / w; x++) { int pos = (int)(totals[x, y] / ppc * chars.Length); char c = chars[pos == chars.Length ? pos - 1 : pos]; writer.Write(c); } if (y != H / h - 1) { writer.WriteLine(); } } writer.Flush(); } }