Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ImageCompression
- {
- public class JPEGParser
- {
- private enum JPEGElementType
- {
- StartOfImage, StartOfFrameBaseline, StartOfFrameProgressive, DefineHuffmanTable, DefineQuantizationTable,
- DefineRestartInterval, StartOfScan, Restart, ApplicationSpecific, Comment, EndOfImage, Padding
- }
- private class JPEGMarker
- {
- public JPEGElementType Type { get; set; }
- public bool VariableLength { get; set; }
- public bool CoreElement { get; set; }
- }
- private class JPEGElement
- {
- public byte Code { get; set; }
- public JPEGMarker Type
- {
- get
- {
- return JPEGTags[Code];
- }
- }
- public byte LenghtOne { get; set; }
- public byte LenghtTwo { get; set; }
- public IEnumerable<byte> Data { get; set; }
- }
- private const byte TagMarker = 255;
- private static readonly Dictionary<byte, JPEGMarker> JPEGTags = new Dictionary<byte, JPEGMarker>() {
- {216, new JPEGMarker { Type = JPEGElementType.StartOfImage, VariableLength = false, CoreElement = false }},
- {192, new JPEGMarker { Type = JPEGElementType.StartOfFrameBaseline, VariableLength = true, CoreElement = true }},
- {194, new JPEGMarker { Type = JPEGElementType.StartOfFrameProgressive, VariableLength = true, CoreElement = true }},
- {196, new JPEGMarker { Type = JPEGElementType.DefineHuffmanTable, VariableLength = true, CoreElement = true }},
- {219, new JPEGMarker { Type = JPEGElementType.DefineQuantizationTable, VariableLength = true, CoreElement = true }},
- {221, new JPEGMarker { Type = JPEGElementType.DefineRestartInterval, VariableLength = true, CoreElement = true }},
- {218, new JPEGMarker { Type = JPEGElementType.StartOfScan, VariableLength = true, CoreElement = true }},
- {208, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {209, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {210, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {211, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {212, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {213, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {214, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {215, new JPEGMarker { Type = JPEGElementType.Restart, VariableLength = false, CoreElement = false }},
- {224, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {225, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {226, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {227, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {228, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {229, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {230, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {231, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {232, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {233, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {234, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {235, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {236, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {237, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {238, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {239, new JPEGMarker { Type = JPEGElementType.ApplicationSpecific, VariableLength = true, CoreElement = false }},
- {254, new JPEGMarker { Type = JPEGElementType.Comment, VariableLength = true, CoreElement = false }},
- {217, new JPEGMarker { Type = JPEGElementType.EndOfImage, VariableLength = false, CoreElement = false }}
- };
- //TODO this has four different HoffmanTables included I should label them all, maybe encapsulate them...
- private static readonly byte[] DefaultHoffmanTables = new byte[] {
- 255, 196, 0, 31, 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 255, 196, 0, 181, 16, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125, 1, 2, 3, 0, 4, 17, 5, 18, 33, 49, 65, 6, 19, 81, 97, 7, 34, 113, 20, 50, 129, 145, 161, 8, 35, 66, 177, 193, 21, 82, 209, 240, 36, 51, 98, 114, 130, 9, 10, 22, 23, 24, 25, 26, 37, 38, 39, 40, 41, 42, 52, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
- 255, 196, 0, 31, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
- 255, 196, 0, 181, 17, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119, 0, 1, 2, 3, 17, 4, 5, 33, 49, 6, 18, 65, 81, 7, 97, 113, 19, 34, 50, 129, 8, 20, 66, 145, 161, 177, 193, 9, 35, 51, 82, 240, 21, 98, 114, 209, 10, 22, 36, 52, 225, 37, 241, 23, 24, 25, 26, 38, 39, 40, 41, 42, 53, 54, 55, 56, 57, 58, 67, 68, 69, 70, 71, 72, 73, 74, 83, 84, 85, 86, 87, 88, 89, 90, 99, 100, 101, 102, 103, 104, 105, 106, 115, 116, 117, 118, 119, 120, 121, 122, 130, 131, 132, 133, 134, 135, 136, 137, 138, 146, 147, 148, 149, 150, 151, 152, 153, 154, 162, 163, 164, 165, 166, 167, 168, 169, 170, 178, 179, 180, 181, 182, 183, 184, 185, 186, 194, 195, 196, 197, 198, 199, 200, 201, 202, 210, 211, 212, 213, 214, 215, 216, 217, 218, 226, 227, 228, 229, 230, 231, 232, 233, 234, 242, 243, 244, 245, 246, 247, 248, 249, 250
- };
- private static IEnumerable<JPEGElement> ParseJPEGData(byte[] input)
- {
- List<JPEGElement> results = new List<JPEGElement>();
- for (int i = 0; i < input.Length; )
- {
- if (input[i] == TagMarker && JPEGTags.ContainsKey(input[i + 1]))
- {
- if (!JPEGTags[input[i + 1]].VariableLength)
- {
- results.Add(new JPEGElement { Code = input[i + 1] });
- i += 2;
- continue;
- }
- else
- {
- var newElement = new JPEGElement
- {
- Code = input[i + 1],
- LenghtOne = input[i + 2],
- LenghtTwo = input[i + 3],
- Data = new List<byte>()
- };
- results.Add(newElement);
- i += 4;
- continue;
- }
- }
- else
- {
- //Some images have data after tags that shouldn't contain data
- //TODO log this somehow or something, here I'm just throwing it away
- if (results.Last().Data != null) ((List<byte>)results.Last().Data).Add(input[i]);
- i++;
- }
- }
- return results;
- }
- private static IEnumerable<byte> JPEGElementToByteArray(JPEGElement input)
- {
- return (new byte[] { TagMarker, JPEGTags.First(a => a.Value.Type == input.Type.Type).Key, input.LenghtOne, input.LenghtTwo }).Concat(input.Data).ToArray();
- }
- private static IEnumerable<byte> JPEGElementsToByteArray(JPEGElement[] input)
- {
- return input.SelectMany(element => element.Type.VariableLength ?
- (new byte[] { TagMarker, JPEGTags.First(a => a.Value.Type == element.Type.Type).Key, element.LenghtOne, element.LenghtTwo }).Concat(element.Data).ToArray() :
- (new byte[] { TagMarker, element.Code }));
- }
- /// <summary>
- /// This method will strip all not image data from the image, attempting to make it as small as possible
- /// </summary>
- /// <param name="parsedInput">The JPEG image in a byte array</param>
- /// <returns>A minimized version, only readable by the complimentery "RestoreJPEGDataFromMinimized"</returns>
- public static IEnumerable<byte> MinimizeJPEGData(byte[] input)
- {
- var parsedInput = ParseJPEGData(input).ToArray();
- var header = parsedInput.First(a => a.Type.Type == JPEGElementType.StartOfFrameBaseline);
- var smallestScan = parsedInput.Where(a => a.Type.Type == JPEGElementType.StartOfScan).OrderBy(a => a.Data.Count()).First();
- return (new byte[] {
- //Height
- header.Data.ToArray()[2],
- //Width
- header.Data.ToArray()[4],
- //TODO: very hacky right now, don't knwo what this does
- header.Data.ToArray()[7]})
- //Now for the StartOfScan, this all needs to be saved except the length 1(assume this is never greater than 255)
- .Concat(new byte[] { smallestScan.LenghtTwo })
- .Concat(smallestScan.Data.ToArray());
- }
- /// <summary>
- /// This method will change code genereated from "MinimizeJPEGData" to a readable JPEG byte array
- /// </summary>
- /// <param name="input">The minimized JPEG image</param>
- /// <returns>Array of bytes constituting a image</returns>
- public static IEnumerable<byte> RestoreJPEGDataFromMinimized(byte[] input)
- {
- //TODO lots of hard coding going on here very unreadable, need to improve this
- var results = new List<byte>();
- //Get basic info
- byte height = input[0];
- byte width = input[1];
- byte headerInfo = input[2];
- //Add startFile
- results.Add(TagMarker);
- results.Add(JPEGTags.First(tag => tag.Value.Type == JPEGElementType.StartOfImage).Key);
- //Add basic QuantizationTables, when quality = 0 these almost always contain 255's
- results.AddRange(new byte[] { 255, 219, 0, 67, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 });
- results.AddRange(new byte[] { 255, 219, 0, 67, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 });
- //Add header information
- results.AddRange(new byte[] { 255, 192, 0, 17, 8, 0, height, 0, width, 3, 1, headerInfo, 0, 2, 17, 1, 3, 17, 1 });
- //Add Custom HoffmanTables
- results.AddRange(DefaultHoffmanTables);
- //Very Important StartOfScan
- results.AddRange(new byte[] { 255, 218, 0 });
- results.AddRange(input.Skip(3).ToArray());
- //Add endFile
- results.Add(TagMarker);
- results.Add(JPEGTags.First(tag => tag.Value.Type == JPEGElementType.EndOfImage).Key);
- return results;
- }
- }
- }
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.IO.Compression;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- using ImageMagick;
- namespace ImageCompression
- {
- public partial class TweetImager : Form
- {
- public TweetImager()
- {
- InitializeComponent();
- }
- private void LoadImageButton_Click(object sender, EventArgs e)
- {
- ImageOpenFileDialog.ShowDialog();
- }
- private void ImageOpenFileDialog_FileOk(object sender, CancelEventArgs e)
- {
- int resizeDimension = 75;
- using (MagickImage imageOriginal = new MagickImage(ImageOpenFileDialog.FileName))
- using (MemoryStream ms = new MemoryStream())
- {
- do
- {
- using (var image = new MagickImage(imageOriginal))
- {
- //Clear the memorystream
- ms.SetLength(0);
- //Resize the image
- image.Resize(new MagickGeometry(resizeDimension));
- // Sets the output format to jpeg
- image.Format = MagickFormat.Jpeg;
- image.Quality = 1;
- //Use default Hoffman table, do not optimize(this allows use to cache the Hoffmantables and not encode them)
- image.SetDefine(MagickFormat.Jpeg, "optimize-coding", "off");
- // Write the image to the memorystream
- image.Write(ms);
- //Encode it too text
- TweetRichTextBox.Text = EncodeBytesToAscii(JPEGParser.MinimizeJPEGData(ms.ToArray()).ToArray());
- }
- resizeDimension--;
- }
- //Reduce the image size until the output text is less than or equal to 140 characters(including height and width parameters)
- while (TweetRichTextBox.Text.ToCharArray().Length > 140);
- }
- }
- private void TranslateButton_Click(object sender, EventArgs e)
- {
- //TODO Will blow up if no file is selected, this all needs to be made better
- var newFileName = ImageOpenFileDialog.FileName.Split('.')[0] + "1.png";
- //Now get the image from the ascii text
- var data = DeencodeAsciiToBytes(TweetRichTextBox.Text).ToArray();
- var file = JPEGParser.RestoreJPEGDataFromMinimized(data).ToArray();
- //Blow up the picture so its easier to see
- var enlaregedResult = new MagickImage(new Bitmap(new Bitmap(new MemoryStream(file)), new Size { Height = data[0] * 4, Width = data[1] * 4 }));
- //Blur helps soften some of the compression
- enlaregedResult.GaussianBlur(7, 35);
- TweetImagePictureBox.Image = enlaregedResult.ToBitmap();
- if (SaveCheckBox.Checked) enlaregedResult.ToBitmap().Save(newFileName, ImageFormat.Png);
- }
- //Ascii Converter
- private static string EncodeBytesToAscii(byte[] input)
- {
- //Not sure this is exactly the most efficient way to store data within range 0-94, should at least be close(I hope)
- List<byte> output = new List<byte>();
- var parsedToBits = input.SelectMany(GeneralHelperFunctions.GetBits).ToList();
- //Numbers between 94 and 64 should be 7, ones below should be 6, if a number is over 94 take 6 automatically making it less than 64
- for (int i = 0; i < parsedToBits.Count(); )
- {
- if (i + 6 < parsedToBits.Count())
- {
- if (GeneralHelperFunctions.ConvertBitArraytoByte(parsedToBits.GetRange(i, 7).ToArray()) > 94 ||
- GeneralHelperFunctions.ConvertBitArraytoByte(parsedToBits.GetRange(i, 7).ToArray()) < 64)
- {
- output.Add(GeneralHelperFunctions.ConvertBitArraytoByte(parsedToBits.GetRange(i, 6).ToArray()));
- i = i + 6;
- }
- else
- {
- output.Add(GeneralHelperFunctions.ConvertBitArraytoByte(parsedToBits.GetRange(i, 7).ToArray()));
- i = i + 7;
- }
- }
- else
- {
- output.Add(GeneralHelperFunctions.ConvertBitArraytoByte(parsedToBits.GetRange(i, parsedToBits.Count() - i).ToArray()));
- break;
- }
- }
- //Add 32 to each number and convert to a character, this should output ASCII characters now
- return String.Join("", output.Select(a => (char)(a + 32)));
- }
- private static IEnumerable<byte> DeencodeAsciiToBytes(string input)
- {
- //Pretty much the opposite of "EncodeBytesToAscii", based on number size pulls all bits from the inputed charcters,
- //then flattens the output and splits by 8 to convert back to base 255
- var result = new List<byte>();
- var inputList = input.ToCharArray()
- .Select(a => ((int)a - 32))
- .SelectMany(a => a >= 64 ? GeneralHelperFunctions.GetBits((byte)a).Skip(1).ToArray() : GeneralHelperFunctions.GetBits((byte)a).Skip(2).ToArray())
- .ToList();
- for (int i = 0; i < inputList.Count; i = i + 8)
- {
- if (inputList.Count - i < 8) result.Add(GeneralHelperFunctions.ConvertBitArraytoByte(inputList.GetRange(i, inputList.Count - i).ToArray()));
- else result.Add(GeneralHelperFunctions.ConvertBitArraytoByte(inputList.GetRange(i, 8).ToArray()));
- }
- return result.ToArray();
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ImageCompression
- {
- class GeneralHelperFunctions
- {
- //Bit/Byte/Char converters
- public static byte ConvertBitArraytoByte(bool[] bits)
- {
- if (bits.Length > 8)
- throw new ArgumentException("No arrays larger than 8 allowed!");
- int result = 0;
- double multiplier = Math.Pow(2, bits.Length - 1);
- foreach (var element in bits)
- {
- if (element) result += (int)multiplier;
- multiplier = multiplier / 2;
- }
- return (byte)result;
- }
- public static IEnumerable<bool> GetBits(byte b)
- {
- for (int i = 0; i < 8; i++)
- {
- yield return (b & 0x80) != 0;
- b *= 2;
- }
- }
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace ImageCompression
- {
- static class Program
- {
- /// <summary>
- /// The main entry point for the application.
- /// </summary>
- [STAThread]
- static void Main()
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new TweetImager());
- }
- }
- }
- namespace ImageCompression
- {
- partial class TweetImager
- {
- /// <summary>
- /// Required designer variable.
- /// </summary>
- private System.ComponentModel.IContainer components = null;
- /// <summary>
- /// Clean up any resources being used.
- /// </summary>
- /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
- #region Windows Form Designer generated code
- /// <summary>
- /// Required method for Designer support - do not modify
- /// the contents of this method with the code editor.
- /// </summary>
- private void InitializeComponent()
- {
- this.LoadImageButton = new System.Windows.Forms.Button();
- this.ImageOpenFileDialog = new System.Windows.Forms.OpenFileDialog();
- this.TweetImagePictureBox = new System.Windows.Forms.PictureBox();
- this.TweetRichTextBox = new System.Windows.Forms.RichTextBox();
- this.TweetLabel = new System.Windows.Forms.Label();
- this.TranslateButton = new System.Windows.Forms.Button();
- this.SaveCheckBox = new System.Windows.Forms.CheckBox();
- ((System.ComponentModel.ISupportInitialize)(this.TweetImagePictureBox)).BeginInit();
- this.SuspendLayout();
- //
- // LoadImageButton
- //
- this.LoadImageButton.Location = new System.Drawing.Point(58, 13);
- this.LoadImageButton.Name = "LoadImageButton";
- this.LoadImageButton.Size = new System.Drawing.Size(75, 23);
- this.LoadImageButton.TabIndex = 0;
- this.LoadImageButton.Text = "LoadImage";
- this.LoadImageButton.UseVisualStyleBackColor = true;
- this.LoadImageButton.Click += new System.EventHandler(this.LoadImageButton_Click);
- //
- // ImageOpenFileDialog
- //
- this.ImageOpenFileDialog.FileName = "ImageOpenFileDialog";
- this.ImageOpenFileDialog.FileOk += new System.ComponentModel.CancelEventHandler(this.ImageOpenFileDialog_FileOk);
- //
- // TweetImagePictureBox
- //
- this.TweetImagePictureBox.Location = new System.Drawing.Point(12, 147);
- this.TweetImagePictureBox.Name = "TweetImagePictureBox";
- this.TweetImagePictureBox.Size = new System.Drawing.Size(250, 250);
- this.TweetImagePictureBox.TabIndex = 3;
- this.TweetImagePictureBox.TabStop = false;
- //
- // TweetRichTextBox
- //
- this.TweetRichTextBox.Location = new System.Drawing.Point(12, 41);
- this.TweetRichTextBox.Name = "TweetRichTextBox";
- this.TweetRichTextBox.Size = new System.Drawing.Size(250, 75);
- this.TweetRichTextBox.TabIndex = 4;
- this.TweetRichTextBox.Text = "";
- //
- // TweetLabel
- //
- this.TweetLabel.AutoSize = true;
- this.TweetLabel.Location = new System.Drawing.Point(12, 22);
- this.TweetLabel.Name = "TweetLabel";
- this.TweetLabel.Size = new System.Drawing.Size(40, 13);
- this.TweetLabel.TabIndex = 5;
- this.TweetLabel.Text = "Tweet:";
- //
- // TranslateButton
- //
- this.TranslateButton.Location = new System.Drawing.Point(12, 122);
- this.TranslateButton.Name = "TranslateButton";
- this.TranslateButton.Size = new System.Drawing.Size(75, 23);
- this.TranslateButton.TabIndex = 6;
- this.TranslateButton.Text = "Translate";
- this.TranslateButton.UseVisualStyleBackColor = true;
- this.TranslateButton.Click += new System.EventHandler(this.TranslateButton_Click);
- //
- // SaveCheckBox
- //
- this.SaveCheckBox.AutoSize = true;
- this.SaveCheckBox.Location = new System.Drawing.Point(93, 126);
- this.SaveCheckBox.Name = "SaveCheckBox";
- this.SaveCheckBox.Size = new System.Drawing.Size(51, 17);
- this.SaveCheckBox.TabIndex = 7;
- this.SaveCheckBox.Text = "Save";
- this.SaveCheckBox.UseVisualStyleBackColor = true;
- //
- // TweetImager
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(284, 411);
- this.Controls.Add(this.SaveCheckBox);
- this.Controls.Add(this.TranslateButton);
- this.Controls.Add(this.TweetLabel);
- this.Controls.Add(this.TweetRichTextBox);
- this.Controls.Add(this.TweetImagePictureBox);
- this.Controls.Add(this.LoadImageButton);
- this.Name = "TweetImager";
- this.Text = "TweetImager";
- ((System.ComponentModel.ISupportInitialize)(this.TweetImagePictureBox)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
- }
- #endregion
- private System.Windows.Forms.Button LoadImageButton;
- private System.Windows.Forms.OpenFileDialog ImageOpenFileDialog;
- private System.Windows.Forms.PictureBox TweetImagePictureBox;
- private System.Windows.Forms.RichTextBox TweetRichTextBox;
- private System.Windows.Forms.Label TweetLabel;
- private System.Windows.Forms.Button TranslateButton;
- private System.Windows.Forms.CheckBox SaveCheckBox;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement