public static Bitmap Combined_Text_Layers(BustupData bustup_data, List <string>[] dialogue_lines) { int template_width = 320; int template_height = 240; Bitmap base_template = new Bitmap(template_width, template_height); Bitmap rendered_name = Render_Name(bustup_data); Bitmap rendered_dialogue = Render_Dialogue(dialogue_lines); Bitmap dialogue_front = rendered_dialogue; Bitmap dialogue_back = Text_To_Black(rendered_dialogue); Bitmap display_name_front = Text_To_Yellow(rendered_name); Bitmap display_name_back = Text_To_Dark_Yellow(rendered_name); using (Graphics graphics = Graphics.FromImage(base_template)) { graphics.DrawImage(display_name_back, 1, 1, template_width, template_height); graphics.DrawImage(display_name_front, 0, 0, template_width, template_height); graphics.DrawImage(dialogue_back, 1, 1, template_width, template_height); graphics.DrawImage(dialogue_front, 0, 0, template_width, template_height); } return(base_template); }
public static Bitmap Render_Bustup(UserInfoFields account, BustupData bustup_data, Bitmap bustup) { int template_width = 320; int template_height = 240; Bitmap base_template = new Bitmap(template_width, template_height); using (Graphics graphics = Graphics.FromImage(base_template)) { switch (account.P2EP_PSX_TS_Position) { case "Default": switch (bustup_data.P2EP_PSX_Default_Position) { case "Left": graphics.DrawImage(bustup, bustup_data.P2EP_PSX_Left_Coord_X, bustup_data.P2EP_PSX_Left_Coord_Y, bustup_data.P2EP_PSX_Scale_Width, bustup_data.P2EP_PSX_Scale_Height); break; case "Center": graphics.DrawImage(bustup, bustup_data.P2EP_PSX_Center_Coord_X, bustup_data.P2EP_PSX_Center_Coord_Y, bustup_data.P2EP_PSX_Scale_Width, bustup_data.P2EP_PSX_Scale_Height); break; case "Right": graphics.DrawImage(bustup, bustup_data.P2EP_PSX_Right_Coord_X, bustup_data.P2EP_PSX_Right_Coord_Y, bustup_data.P2EP_PSX_Scale_Width, bustup_data.P2EP_PSX_Scale_Height); break; } break; case "Negotiation": graphics.DrawImage(bustup, bustup_data.P2EP_PSX_Right_Coord_X, bustup_data.P2EP_PSX_Right_Coord_Y, bustup_data.P2EP_PSX_Scale_Width, bustup_data.P2EP_PSX_Scale_Height); break; } } return(base_template); }
public static async Task Render_Quick_Scene_P4D(SocialLinkerCommand sl_command, OfficialSetData set_data, MakerCommandData command_data) { // Create variables to store the width and height of the template. int template_width = 1920; int template_height = 1080; // Create two variables for the command user and the command channel, derived from the message object taken in. SocketUser user = sl_command.User; SocketTextChannel channel = (SocketTextChannel)sl_command.Channel; // Send a loading message to the channel while the sprite sheet is being made. RestUserMessage loader = await channel.SendMessageAsync("", false, P4D_Loading_Message().Build()); // Get the account information of the command's user. var account = UserInfoClasses.GetAccount(user); BustupData bustup_data = BustupDataMethods.Get_Bustup_Data(account, set_data, command_data); // Create a starting base bitmap to render all graphics on. Bitmap base_template = new Bitmap(template_width, template_height); // Create another bitmap the same size. // In case the user has set a colored bitmap in their settings, we'll need to use this to render it. Bitmap colored_background_bitmap = new Bitmap(template_width, template_height); // Here, we want to grab any images attached to the message to use it as a background. // Create a variable for the message attachment. var attachments = sl_command.Attachments; // Create an empty string variable to hold the URL of the attachment. string url = ""; // If there are no attachments on the message, set the URL string to "None". if (attachments == default || attachments.LongCount() == 0) { url = "None"; } // Else, assign the URL of the attachment to the URL string. else { url = attachments.ElementAt(0).Url; } // Initialize a bitmap object for the user's background. It's small now because we'll reassign it depending on our circumstances. Bitmap background = new Bitmap(2, 2); // If a URL for a message attachment exists, download it and copy its contents to the bitmap variable we just created. if (url != "None") { // Here, we'll want to try and retrieve the user's input image. try { // Declare variables for a web request to retrieve the image. System.Net.HttpWebRequest webRequest = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url); webRequest.AllowWriteStreamBuffering = true; webRequest.Timeout = 30000; // Create a stream and download the image to it. System.Net.WebResponse webResponse = webRequest.GetResponse(); System.IO.Stream stream = webResponse.GetResponseStream(); // Copy the stream's contents to the background bitmap variable. background = (Bitmap)System.Drawing.Image.FromStream(stream); webResponse.Close(); } // If an exception occurs here, the filetype is likely incompatible. // Send an error message, delete the loading message, and return. catch (System.ArgumentException e) { Console.WriteLine(e); await loader.DeleteAsync(); _ = ErrorHandling.Incompatible_File_Type(sl_command); return; } } // Render the uploaded image based on the user's background settings. switch (account.Setting_BG_Upload) { case "Maintain Aspect Ratio": background = Center_Image(background); break; case "Stretch to Fit": background = Stretch_To_Fit(background); break; } // The user may have a custom mono-colored background designated in their settings. Let's handle that now. // Check if the user's background color setting is set to something other than "Transparent". // If so, we have a color to render for the background! if (account.Setting_BG_Color != "Transparent") { // Convert the user's HTML color setting to one we can use and assign it to a color variable. System.Drawing.Color user_background_color = System.Drawing.ColorTranslator.FromHtml(account.Setting_BG_Color); // Color the entirety of the background bitmap the user's selected color. using (Graphics graphics = Graphics.FromImage(colored_background_bitmap)) { graphics.Clear(user_background_color); } } // Next, time for the conversation portrait! Create and initialize a new bitmap variable for it. Bitmap bustup = new Bitmap(2, 2); // Check if the base sprite number is something other than zero. // If it is zero, we have nothing to render. Otherwise, retrieve the bustup. if (command_data.Base_Sprite != 0) { bustup = OfficialSetMethods.Bustup_Selection(sl_command, account, set_data, bustup_data, command_data); } // If the bustup returns as null, however, something went wrong with rendering the animation frames. // An error message has already been sent in the frame rendering method, so delete the loading message and return. if (bustup == null) { await loader.DeleteAsync(); return; } // Time to put it all together! using (Graphics graphics = Graphics.FromImage(base_template)) { // Draw the layer with the user's colored default background if it exists. graphics.DrawImage(colored_background_bitmap, 0, 0, template_width, template_height); // Draw the user's background to the base template. graphics.DrawImage(background, 0, 0, template_width, template_height); // Draw the character bust-up to the template if the base sprite number is not '0'. if (command_data.Base_Sprite != 0) { graphics.DrawImage(bustup, bustup_data.P4D_Center_Coord_X, bustup_data.P4D_Center_Coord_Y, bustup_data.P4D_Scale_Width, bustup_data.P4D_Scale_Height); } // Now, it's time to render the text. // Render the character's name to the template. // Check if the base sprite number is something other than zero. if (command_data.Base_Sprite != 0) { //graphics.DrawImage(Text_To_Blue(Render_Name(bustup_data)), 0, 0, template_width, template_height); } // If the base sprite number IS zero, we need a sprite to actually retrieve a display name from. else { // Change the base sprite number from the command data to one. // This way, we can get the bustup data for the first sprite to retrieve its display name. command_data.Base_Sprite = 1; // Get the bustup data for the first sprite and render the display name to the template. bustup_data = BustupDataMethods.Get_Bustup_Data(account, set_data, command_data); //graphics.DrawImage(Text_To_Blue(Render_Name(bustup_data)), 0, 0, template_width, template_height); } // Draw the input dialogue to the template. //graphics.DrawImage(Render_Dialogue(Line_Parser(sl_command, command_data.Dialogue)), 0, 0, template_width, template_height); } // Save the entire base template to a data stream. MemoryStream memoryStream = new MemoryStream(); base_template.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png); memoryStream.Seek(0, SeekOrigin.Begin); try { // Send the image. await sl_command.Channel.SendFileAsync(memoryStream, $"scene_{sl_command.User.Id}_{DateTime.UtcNow}.png"); } catch (Exception e) { Console.WriteLine(e); // Send an error message to the user if the image upload fails. _ = ErrorHandling.Image_Upload_Failed(sl_command); // Clean up resources used by the stream, delete the loading message, and return. memoryStream.Dispose(); await loader.DeleteAsync(); return; } // Clean up resources used by the stream and delete the loading message. memoryStream.Dispose(); await loader.DeleteAsync(); // If the user has auto-delete for their commands set to on, delete their command as well. if (account.Auto_Delete_Commands == "On") { await sl_command.Message.DeleteAsync(); } }
public static Bitmap Render_Name(BustupData bustup_data) { // Create a bitmap as large as the template. Bitmap base_template = new Bitmap(1920, 1080); // Establish an int for the width and height glyphs should be rendered at. int multiplier = 64; // Load the bitmap font. string font_sheet = $@"{AssetDirectoryConfig.assetDirectory.assetFolderPath}//SceneMaker//Templates//P4G//Font//p4g_font_sheet.png"; // Create a variable to iterate through sections of the bitmap font. Bitmap current_glyph; // Specify X and Y coordinates for where the glyphs should start rendering on the template. int render_position_x = 102; int render_position_y = 748; char[] charArr = bustup_data.Default_Name_EN.ToCharArray(); for (int i = 0; i < charArr.Length; i++) { // Retrieve glyph information from the JSON file. var glyph = ParsingMethods.Get_P4G_Glyph(charArr[i]); // Check if the character is a line break. if (charArr[i] == '\u000a') { // Set the X coordinate to the start of the row. render_position_x = 124; // Move the Y coordinate down to the next line. render_position_y += 68; } else { int x = multiplier * glyph.Column; int y = multiplier * glyph.Row; using (Graphics graphics = Graphics.FromImage(base_template)) { using (var originalImage = new Bitmap(font_sheet)) { // Copy the section of the bitmap font needed. Rectangle crop = new Rectangle(x, y, multiplier, multiplier); current_glyph = originalImage.Clone(crop, originalImage.PixelFormat); // Draw the glyph to the base bitmap. graphics.DrawImage(current_glyph, (render_position_x - glyph.LeftCut), render_position_y, multiplier, multiplier); } } // Set the next X value at the end of the current glyph's right width. render_position_x += (glyph.RightCut - glyph.LeftCut); // Check if the current iterated index is less than the number of indicies available. if (i < charArr.Length - 1) { // If so, edit the position of the X coordinate according to specific kerning pairs. if (charArr[i] == 'Y' && Char.IsLower(charArr[i + 1])) { render_position_x += -6; } else if (charArr[i] == 'v' && Char.IsLower(charArr[i + 1])) { render_position_x += -1; } else if (charArr[i] == 'T' && Char.IsLower(charArr[i + 1]) && charArr[i + 1] != 'h') { render_position_x += -6; } } } } return(base_template); }
public static Bitmap Render_Name(BustupData bustup_data) { // Create variables to store the width and height of the template. int template_width = 320; int template_height = 240; Bitmap base_template = new Bitmap(template_width, template_height); // Establish ints for the width and height of glyphs. int x_multiplier = 8; int y_multiplier = 12; // Load the bitmap font. string font_sheet = $@"{AssetDirectoryConfig.assetDirectory.assetFolderPath}//SceneMaker//Templates//P2EP-PS1//Font//p2ep-ps1_font_sheet.png"; // Create a variable to iterate through sections of the bitmap font. Bitmap current_glyph; // Specify X and Y coordinates for where the glyphs should start rendering on the template. int render_position_x = 16; int render_position_y = 171; // Take the sprite's display name and convert it into a char array. char[] char_array = bustup_data.Default_Name_EN.ToCharArray(); // Iterate through each character of the array. for (int i = 0; i < char_array.Length; i++) { // Retrieve glyph information from the JSON file. var glyph = ParsingMethods.Get_P2EP_PS1_Glyph(char_array[i]); // Check if the character is a line break. if (char_array[i] == '\u000a') { // Set the X coordinate to the start of the row. render_position_x = 16; // Move the Y coordinate down to the next line. render_position_y += 14; } else { int x = x_multiplier * glyph.Column; int y = y_multiplier * glyph.Row; using (Graphics graphics = Graphics.FromImage(base_template)) { using (var originalImage = new Bitmap(font_sheet)) { // Copy the section of the bitmap font needed. Rectangle crop = new Rectangle(x, y, x_multiplier, y_multiplier); current_glyph = originalImage.Clone(crop, originalImage.PixelFormat); // Draw the glyph to the base bitmap. Some hanging letters will need to be drawn a bit lower to appear natural. if (char_array[i] == 'g' || char_array[i] == 'j' || char_array[i] == 'p' || char_array[i] == 'q' || char_array[i] == 'y') { graphics.DrawImage(current_glyph, (render_position_x - glyph.LeftCut), render_position_y + 1, x_multiplier, y_multiplier); } else { graphics.DrawImage(current_glyph, (render_position_x - glyph.LeftCut), render_position_y, x_multiplier, y_multiplier); } } } // Set the next X value at the end of the current glyph's right width. render_position_x += (glyph.RightCut - glyph.LeftCut) + 1; } } return(base_template); }