Reputation: 978
I'm trying to create a tiled background using the Lumia Imaging SDK's JpegTools.BlendAsync()
method. I call the method in a loop to merge all the tiled images. The approach works but the there are unwanted lines in the output image. These separation lines appear at the boundaries of the single tile image; the merging is not clean.
My code is attached. Am I doing something wrong logically or this is a bug in the SDK?
bitmapSource
is the single tile, jpegSource
is the empty layout which is populated by the tile, and bgSize
is the size of the dimensions of the background.
async private static Task<IBuffer> CreateTile(IBuffer jpegSource, IReadableBitmap bitmapSource, Size tileSize, Size bgSize)
{
int outBgWidth = (int)bgSize.Width;
int outBgHeight = (int)bgSize.Height;
int tileWidth = (int)tileSize.Width;
int tileHeight = (int)tileSize.Height;
int currentBgWidth = 0;
int currentBgHeight = 0;
Point blendPosition = new Point(0, 0);
while (currentBgHeight < outBgHeight)
{
while (currentBgWidth < outBgWidth)
{
jpegSource = await JpegTools.BlendAsync(jpegSource, bitmapSource, blendPosition);
blendPosition.X += tileWidth;
currentBgWidth += tileWidth;
}
blendPosition.Y += tileHeight;
currentBgHeight += tileHeight;
currentBgWidth = 0;
blendPosition.X = 0;
}
return jpegSource;
}
Upvotes: 1
Views: 246
Reputation: 17607
As discussed in the comments, I suggest an alternate way of doing this: By using a more "standard" rendering chain, instead of using JpegTools.
Some of this is based on your code sample, but I've tried making it as general as possible.
int outBgWidth = (int)bgSize.Width;
int outBgHeight = (int)bgSize.Height;
int tileWidth = (int)tileSize.Width;
int tileHeight = (int)tileSize.Height;
int currentBgWidth = 0;
int currentBgHeight = 0;
Point blendPosition = new Point(0, 0);
using (var backgroundCanvas = new ColorImageSource(new Size(outBgWidth, outBgHeight), Color.FromArgb(255, 0, 0, 0))) //Create a black canvas with the output size.
using (var tileSource = new BitmapImageSource(bitmapSource))
using (var renderer = new JpegRenderer(backgroundCanvas))
{
while (currentBgHeight < outBgHeight)
{
while (currentBgWidth < outBgWidth)
{
var blendEffect = new BlendEffect();
blendEffect.BlendFunction = BlendFunction.Normal;
blendEffect.GlobalAlpha = 1.0;
blendEffect.Source = renderer.Source;
blendEffect.ForegroundSource = tileSource;
blendEffect.TargetArea = new Rect(blendPosition, new Size(0, 0)); //Since we are PreservingSize the size doesn't matter. Otherwise it must be in relative coordinate space!
blendEffect.TargetOutputOption = OutputOption.PreserveSize;
renderer.Source = blendEffect;
currentBgWidth += tileWidth;
blendPosition.X = (double)currentBgWidth / (double)outBgWidth; //Careful, the target area is in relative coordinates
}
currentBgHeight += tileHeight;
blendPosition.Y = (double)currentBgHeight / (double)outBgHeight; //Careful, the target area is in relative coordinates
blendPosition.X = 0.0;
currentBgWidth = 0;
}
var result = await renderer.RenderAsync(); //An IBuffer containing the Jpeg file
}
I have tried this solution in a sample and I can't see any artifacts. Please do come back and report your results though!
Upvotes: 2