Skip to content

Commit abe4376

Browse files
committed
Don't mirror if extra padding available
1 parent 60edfad commit abe4376

File tree

2 files changed

+55
-22
lines changed

2 files changed

+55
-22
lines changed

BookCoverCreator.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net9.0</TargetFramework>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<Nullable>enable</Nullable>
88
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
12+
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.6" />
1313
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4" />
1414
</ItemGroup>
1515

BookCoverCreatorApp.cs

+53-20
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,9 @@ public static void Main(string[] args)
8585
string frontCoverResized = Path.Combine(outputFolder, "05-FrontCover.png");
8686
string frontCoverFileMirrored = Path.Combine(outputFolder, "03-FrontCoverMirrored.png");
8787
Directory.CreateDirectory(outputFolder);
88-
ProcessSpine(spineFile, spineFileFaded);
8988
ProcessCover(backCoverFile, backCoverFileResized, backCoverFileMirrored, true);
9089
ProcessCover(frontCoverFile, frontCoverResized, frontCoverFileMirrored, false);
91-
90+
ProcessSpine(spineFile, spineFileFaded);
9291
Console.WriteLine("Image processing complete. You can now take the files from the output folder at {0} and put them into your template image as individual layers.");
9392
Console.WriteLine("Top down order is: ");
9493
Console.WriteLine("01-SpineBlend.png");
@@ -187,45 +186,77 @@ private static void AssignVariables(Dictionary<string, string> dict)
187186
backCoverMirrorRectDest = new(spineRect.X, 0, spineRect.Width / 2, spineRect.Height);
188187
backCoverMirrorRectSource = new(0, 0, spineRect.Width / 2, spineRect.Height);
189188
frontCoverRect = new(backWidth + spineWidth, 0, frontWidth, finalHeight);
190-
frontCoverMirrorRectDest = new(spineRect.Left + (spineRect.Width / 2), 0, spineRect.Width / 2, 0);
189+
frontCoverMirrorRectDest = new(spineRect.Left + (spineRect.Width / 2), 0, spineRect.Width / 2, spineRect.Height);
191190
frontCoverMirrorSource = new(frontCoverRect.Width - (spineRect.Width / 2), 0, (spineRect.Width / 2), spineRect.Height);
192191
}
193192

194193
private static void ProcessCover(string inputFilePath, string outputFileResized, string outputFileMirrored, bool isBackCover)
195194
{
196-
using Image<Rgba32> coverImage = Image.Load<Rgba32>(inputFilePath);
197-
Crop(coverImage, aspectRatioCover);
195+
using var coverImage = Image.Load<Rgba32>(inputFilePath);
196+
using var croppedImage = Crop(coverImage, aspectRatioCover);
198197

199198
// Create the final image
200-
using Image<Rgba32> finalImage = new(finalRect.Width, finalRect.Height, Color.Transparent);
199+
var finalImage = new Image<Rgba32>(finalRect.Width, finalRect.Height, Color.Transparent);
201200

202201
// Calculate positions to position the resized image
203202
Rectangle coverRectDest = isBackCover ? backCoverRect : frontCoverRect;
204203
Rectangle mirrorRectDest = isBackCover ? backCoverMirrorRectDest : frontCoverMirrorRectDest;
205204
Rectangle mirrorRectSource = isBackCover ? backCoverMirrorRectSource : frontCoverMirrorSource;
206205

207-
208206
// Draw the resized image onto the final image
209-
coverImage.Mutate(ctx => ctx.Resize(new Size(coverRectDest.Width, coverRectDest.Height)));
210-
finalImage.Mutate(ctx => ctx.DrawImage(coverImage, new Point(coverRectDest.X, coverRectDest.Y), 1.0f));
207+
using var croppedImageResized = croppedImage.Clone(ctx => ctx.Resize(new Size(coverRectDest.Width, coverRectDest.Height)));
208+
finalImage.Mutate(ctx => ctx.DrawImage(croppedImageResized, new Point(coverRectDest.X, coverRectDest.Y), 1.0f));
211209

212210
// Save the final image
213211
finalImage.Save(outputFileResized);
214212

215-
// Create the mirrored image
216-
using Image<Rgba32> mirroredImage = new(coverRectDest.Width, coverRectDest.Height);
217-
mirroredImage.Mutate(ctx => ctx.DrawImage(coverImage, new Point(0, 0), 1.0f));
218-
mirroredImage.Mutate(ctx => ctx.Flip(FlipMode.Horizontal));
213+
// Re-use final image for mirroring
214+
finalImage.Dispose();
215+
finalImage = new Image<Rgba32>(finalRect.Width, finalRect.Height, Color.Transparent);
216+
217+
// If we have space, extend the image instead of mirroring
218+
float widthRatio = (float)croppedImageResized.Width / (float)croppedImage.Width;
219+
220+
// Convert from cropt resize measures to original image measures
221+
int neededGap = (int)((float)mirrorRectSource.Width / widthRatio);
222+
int actualGap = (coverImage.Width - croppedImage.Width) / 2;
223+
if (neededGap <= actualGap)
224+
{
225+
// Extract the edge of the cover, using the right side for back and left side for front,
226+
// then draw this onto the final image at the mirror position
227+
// Create a crop rect that takes into account the original cover size and the final cover size
228+
int croppedX = ((coverImage.Width - croppedImage.Width) / 2);
229+
int x = isBackCover ? croppedImage.Width + croppedX : croppedX - neededGap;
230+
int y = (croppedImage.Height - coverImage.Height) / 2;
231+
int width = neededGap;
232+
int height = croppedImage.Height;
233+
var cropRect = new Rectangle(x, y, width, height);
234+
using var edgeImage = coverImage.Clone(ctx =>
235+
{
236+
ctx.Crop(cropRect);
237+
ctx.Resize(mirrorRectDest.Width, mirrorRectDest.Height);
238+
});
239+
finalImage.Mutate(ctx => ctx.DrawImage(edgeImage, new Point(mirrorRectDest.X, mirrorRectDest.Y), 1.0f));
240+
}
241+
else
242+
{
243+
// Create the mirrored image
244+
using var mirroredImage = new Image<Rgba32>(coverRectDest.Width, coverRectDest.Height);
245+
246+
// Draw image and mirror it
247+
mirroredImage.Mutate(ctx => ctx.DrawImage(croppedImageResized, new Point(0, 0), 1.0f));
248+
mirroredImage.Mutate(ctx => ctx.Flip(FlipMode.Horizontal));
219249

220-
// extract the mirror rect source from the mirrored image
221-
using Image<Rgba32> mirroredImageSource = mirroredImage.Clone(ctx => ctx.Crop(mirrorRectSource));
250+
// Extract the mirror rect source from the mirrored image
251+
using var mirroredImageSource = mirroredImage.Clone(ctx => ctx.Crop(mirrorRectSource));
222252

223-
// Draw the mirrored image onto the final image
224-
finalImage.Mutate(ctx => ctx.Clear(Color.Transparent));
225-
finalImage.Mutate(ctx => ctx.DrawImage(mirroredImageSource, new Point(mirrorRectDest.X, mirrorRectDest.Y), 1.0f));
253+
// Draw the mirrored image onto the final image
254+
finalImage.Mutate(ctx => ctx.DrawImage(mirroredImageSource, new Point(mirrorRectDest.X, mirrorRectDest.Y), 1.0f));
255+
}
226256

227257
// Save the mirrored image
228258
finalImage.Save(outputFileMirrored);
259+
finalImage.Dispose();
229260
}
230261

231262
private static void ProcessSpine(string inputFilePath, string outputFilePath)
@@ -252,7 +283,7 @@ private static void ProcessSpine(string inputFilePath, string outputFilePath)
252283
finalImage.Save(outputFilePath);
253284
}
254285

255-
private static void Crop(Image<Rgba32> image, double aspectRatio)
286+
private static Image<Rgba32> Crop(Image<Rgba32> image, double aspectRatio)
256287
{
257288
// Calculate the desired dimensions of the cropped image
258289
var imageAspectRatio = (double)image.Width / (double)image.Height;
@@ -264,7 +295,9 @@ private static void Crop(Image<Rgba32> image, double aspectRatio)
264295
var y = (image.Height - cropHeight) / 2;
265296

266297
// Crop the image
267-
image.Mutate(ctx => ctx.Crop(new Rectangle(x, y, cropWidth, cropHeight)));
298+
var croppedImage = image.Clone();
299+
croppedImage.Mutate(ctx => ctx.Crop(new Rectangle(x, y, cropWidth, cropHeight)));
300+
return croppedImage;
268301
}
269302

270303
private static void RemoveBlackRows(Image<Rgba32> image)

0 commit comments

Comments
 (0)