I have created this code
Uri _blendImageUri = new Uri(#"Assets/1.png", UriKind.Relative);
var _blendImageProvider = new StreamImageSource((System.Windows.Application.GetResourceStream(_blendImageUri).Stream));
var bf = new BlendFilter(_blendImageProvider);
Filter work nice. But I want change image size for ForegroundSource property. How can I load image with my size?
If I understood you correctly you are trying to blend ForegroundSource with only a part of the original image? That is called local blending at it is currently not supported on the BlendFilter itself.
You can however use ReframingFilter to reframe the ForegroundSource and then blend it. Your chain will look like something like this:
using (var mainImage = new StreamImageSource(...))
using (var filterEffect = new FilterEffect(mainImage))
{
using (var secondaryImage = new StreamImageSource(...))
using (var secondaryFilterEffect = new FilterEffect(secondaryImage))
using (var reframing = new ReframingFilter(new Rect(0, 0, 500, 500), 0)) //reframe your image, thus "setting" the location and size of the content when blending
{
secondaryFilterEffect.Filters = new [] { reframing };
using (var blendFilter = new BlendFilter(secondaryFilterEffect)
using (var renderer = new JpegRenderer(filterEffect))
{
filterEffect.Filters = new [] { blendFilter };
await renderer.RenderAsync();
}
}
}
As you can see, you can use the reframing filter to position the content of your ForegroundSource so that it will only blend locally. Note that when reframeing you can set the borders outside of the image location (for example new Rect(-100, -100, 500, 500)) and the areas outside of the image will appear as black transparent areas - exactly what you need in BlendFilter.
Related
I am using SharpDX to basically render browser (chromium) output buffer on directX process.
Process is relatively simple, I intercept CEF buffer (by overriding OnPaint method) and write that to a texture2D.
Code is relatively simple:
Texture creation:
public void BuildTextureWrap() {
var oldTexture = texture;
texture = new D3D11.Texture2D(DxHandler.Device, new D3D11.Texture2DDescription() {
Width = overlay.Size.Width,
Height = overlay.Size.Height,
MipLevels = 1,
ArraySize = 1,
Format = DXGI.Format.B8G8R8A8_UNorm,
SampleDescription = new DXGI.SampleDescription(1, 0),
Usage = D3D11.ResourceUsage.Default,
BindFlags = D3D11.BindFlags.ShaderResource,
CpuAccessFlags = D3D11.CpuAccessFlags.None,
OptionFlags = D3D11.ResourceOptionFlags.None,
});
var view = new D3D11.ShaderResourceView(
DxHandler.Device,
texture,
new D3D11.ShaderResourceViewDescription {
Format = texture.Description.Format,
Dimension = D3D.ShaderResourceViewDimension.Texture2D,
Texture2D = { MipLevels = texture.Description.MipLevels },
}
);
textureWrap = new D3DTextureWrap(view, texture.Description.Width, texture.Description.Height);
if (oldTexture != null) {
obsoleteTextures.Add(oldTexture);
}
}
That piece of code is executed at start and when resize is happening.
Now when CEF OnDraw I basically copy their buffer to texture:
var destinationRegion = new D3D11.ResourceRegion {
Top = Math.Min(r.dirtyRect.y, texDesc.Height),
Bottom = Math.Min(r.dirtyRect.y + r.dirtyRect.height, texDesc.Height),
Left = Math.Min(r.dirtyRect.x, texDesc.Width),
Right = Math.Min(r.dirtyRect.x + r.dirtyRect.width, texDesc.Width),
Front = 0,
Back = 1,
};
// Draw to the target
var context = targetTexture.Device.ImmediateContext;
context.UpdateSubresource(targetTexture, 0, destinationRegion, sourceRegionPtr, rowPitch, depthPitch);
There are some more code out there but basically this is only relevant piece. Whole thing works until OnDraw happens frequently.
Apparently if I force CEF to Paint frequently, whole host process dies.
This is happening at UpdateSubresource.
So my question is, is there another, safer way to do this? (Update texture frequently)
Solution to this problem was relatively simple yet not so obvious at the beginning.
I simply moved the code responsible for updating texture inside render loop and just keep internal buffer pointer cached.
I'm using Xamarin.Forms with Urhosharp in my project. I'm tring to set a matrial from an image on a sphere, everything is OK in my Android project but in iOS project, when I set material from some jpg files it doesn't work and all I get is a black screen.
Here is the jpg that works correctly:
And here is the other one that doesn't:
This is my code:
var scene = new Scene();
scene.CreateComponent<Octree>();
// Node (Rotation and Position)
var node = scene.CreateChild("room");
node.Position = new Vector3(0, 0, 0);
//node.Rotation = new Quaternion(10, 60, 10);
node.SetScale(1f);
// Model
var modelObject = node.CreateComponent<StaticModel>();
modelObject.Model = ResourceCache.GetModel("CustomModels/SmoothSphere.mdl");
var zoneNode = scene.CreateChild("Zone");
var zone = zoneNode.CreateComponent<Zone>();
zone.SetBoundingBox(new BoundingBox(-300.0f, 300.0f));
zone.AmbientColor = new Color(1f, 1f, 1f);
//get image from byte[]
//var url = "http://www.wsj.com/public/resources/media/0524yosemite_1300R.jpg";
//var wc = new WebClient() { Encoding = Encoding.UTF8 };
//var mb = new MemoryBuffer(wc.DownloadData(new Uri(url)));
var mb = new MemoryBuffer(PanoramaBuffer.PanoramaByteArray);
var image = new Image(Context) { Name = "MyImage" };
image.Load(mb);
//or from resource
//var image = ResourceCache.GetImage("Textures/grave.jpg");
var isFliped = image.FlipHorizontal();
if (!isFliped)
{
throw new Exception("Unsuccessful flip");
}
var m = Material.FromImage("1.jpg");
m.SetTechnique(0, CoreAssets.Techniques.DiffNormal, 0, 0);
m.CullMode = CullMode.Cw;
//m.SetUVTransform(Vector2.Zero, 0, 0);
modelObject.SetMaterial(m);
// Camera
var cameraNode = scene.CreateChild("camera");
_camera = cameraNode.CreateComponent<Camera>();
_camera.Fov = 75.8f;
_initialZoom = _camera.Zoom;
// Viewport
Renderer.SetViewport(0, new Viewport(scene, _camera, null));
I already tried to change compression level, ICCC profile and ...
I asked the same question in forums.xamarin.com and someone answered the question and I'll share it here :
In iOS every texture needs to have a power of two resolution, like 256 x 256 or 1024 x 512. Check if that is the issue. Additionally check that your using the latest UrhoSharp version.
Also make sure that the image is set as BundleResource in the iOS project.
I am trying to use SKPictureRecorder of SkiaSharp to draw a path in the SKCanvas. The image is not saved in the disk. Please find the code below for your reference.
SKPictureRecorder record = new SKPictureRecorder();
SKCanvas tempCanvas= record.BeginRecording(new SKRect(0,0,640,480));
tempCanvas.Clear(SKColors.White);
// set up drawing tools
using (var paint = new SKPaint())
{
paint.IsAntialias = true;
paint.Color = new SKColor(0x2c, 0x3e, 0x50);
paint.StrokeCap = SKStrokeCap.Round;
// create the Xamagon path
using (var path = new SKPath())
{
path.MoveTo(71.4311121f, 56f);
path.CubicTo(68.6763107f, 56.0058575f, 65.9796704f, 57.5737917f, 64.5928855f, 59.965729f);
path.LineTo(43.0238921f, 97.5342563f);
path.CubicTo(41.6587026f, 99.9325978f, 41.6587026f, 103.067402f, 43.0238921f, 105.465744f);
path.LineTo(64.5928855f, 143.034271f);
path.CubicTo(65.9798162f, 145.426228f, 68.6763107f, 146.994582f, 71.4311121f, 147f);
path.LineTo(114.568946f, 147f);
path.CubicTo(117.323748f, 146.994143f, 120.020241f, 145.426228f, 121.407172f, 143.034271f);
path.LineTo(142.976161f, 105.465744f);
path.CubicTo(144.34135f, 103.067402f, 144.341209f, 99.9325978f, 142.976161f, 97.5342563f);
path.LineTo(121.407172f, 59.965729f);
path.CubicTo(120.020241f, 57.5737917f, 117.323748f, 56.0054182f, 114.568946f, 56f);
path.LineTo(71.4311121f, 56f);
path.Close();
// draw the Xamagon path
tempCanvas.DrawPath(path, paint);
}
}
SKPicture picture= record.EndRecording();
using (var image = SKImage.FromPicture(picture, new SKSizeI(640, 480)))
using (var data = image.Encode(SKEncodedImageFormat.Png, 80))
{
// save the data to a stream
using (var stream = File.OpenWrite("testing.png"))
{
data.SaveTo(stream);
}
}
Can you check any issue with the code?
Also please let us me know the structure of SKPictureRecorder of SkiaSharp.
Thanks in advance.
Regards,
Sabari
I am having a tough time converting lumia imaging SDK 2.0 code to SDK3.0 in below specific case. I used to increase/decrease the image quality of JPG file using below code in Windows phone 8.1 RT apps:
using (StreamImageSource source = new StreamImageSource(fileStream.AsStreamForRead()))
{
IFilterEffect effect = new FilterEffect(source);
using (JpegRenderer renderer = new JpegRenderer(effect))
{
renderer.Quality = App.COMPRESSION_RATIO / 100.0; // higher value means better quality
compressedImageBytes = await renderer.RenderAsync();
}
}
Now since FilterEffect class has been replaced in SDK 3.0 with EffectList(), I changed code to
using (BufferProviderImageSource source = new BufferProviderImageSource(fileStream.AsBufferProvider()))
{
using (JpegRenderer renderer = new JpegRenderer())
{
IImageProvider2 source1 = new EffectList() { Source = source };
renderer.Source = source1;
renderer.Quality = App.COMPRESSION_RATIO / 100.0;
try
{
var img = await renderer.RenderAsync();
}
catch (Exception ex)
{
;
}
}
}
I am getting InvalidCastException exception. I have tried several combinations but no luck.
I don't really know what is going on with the InvalidCastException, we can continue that discussion in the comments as it will most likely need some back-and-forth.
That said, you could continue without the effect list, and chain effects in the normal way. So to rewrite your scenario:
using (var soruce = new StreamImageSource(...))
using (var renderer = new JpegRenderer(source))
{
renderer.Quality = App.COMPRESSION_RATIO / 100.0;
var img = await renderer.RenderAsync();
}
If you wanted to add an effect (for example a CarttonEffect), just do:
using (var soruce = new StreamImageSource(...))
using (var caroonEffect = new CartoonEffect(source))
using (var renderer = new JpegRenderer(caroonEffect))
{
renderer.Quality = App.COMPRESSION_RATIO / 100.0;
var img = await renderer.RenderAsync();
}
and so on. If you had effects A, B, C and D just make a chain Source -> A -> B -> C -> D -> JpegRenderer.
I am on VS 2015 community version. While digging around this, I got below code working which works exactly same as SDK 2.0. All I did was specified the Size of JpegRenderer. It works for all landscape images but fails to transform the portrait images to correct orientation. There is no exception but result of portrait image is widely stretched landscape image.
I initialized the Size for portrait images to Size(765, 1024) but no impact.
using (JpegRenderer renderer = new JpegRenderer(source))
{
renderer.Quality = App.COMPRESSION_RATIO / 100.0;
try
{
var info = await source.GetInfoAsync();
renderer.Size = new Size(1024, 765);
compressedImageBytes = await renderer.RenderAsync();
}
catch (Exception ex)
{
new MessageDialog("Error while compressing.").ShowAsync();
}
}
I am sorry the working code was using BufferProviderImageSource instead StreamImageSource. Below is the snippet. Few points here:
1) If I don't use Size property I get "The component cannot be found exception".
2) GetInfoAsync(): Yes it was useless for above code but I need to use it to know if image is Landscape or Portrait so that I can initialize Size property of resultant image.
3) If Size property goes beyond 1024x1024 for portrait images I get the exception "Value does not fall within the expected range"
Why lumia made this version so tricky. :(
var stream = FileIO.ReadBufferAsync(file);
using (var source = new BufferProviderImageSource(stream.AsBufferProvider()))
{
EffectList list = new EffectList() { Source = source };
using (JpegRenderer renderer = new JpegRenderer(list))
{
renderer.Quality = App.COMPRESSION_RATIO / 100.0;
renderer.OutputOption = OutputOption.PreserveAspectRatio;
try
{
var info = await source.GetInfoAsync();
double width = 0;
double height = 0;
if (info.ImageSize.Width > info.ImageSize.Height) //landscape
{
width = 1024;
height = 765;
if (info.ImageSize.Width < 1024)
width = info.ImageSize.Width;
if (info.ImageSize.Height < 765)
height = info.ImageSize.Height;
}
else //portrait..
{
width = 765;
height = 1024;
if (info.ImageSize.Width < 765)
width = info.ImageSize.Width;
if (info.ImageSize.Height < 1024)
height = info.ImageSize.Height;
}
renderer.Size = new Size(width, height);
compressedImageBytes = await renderer.RenderAsync();
}
catch (Exception ex)
{
new MessageDialog(ex.Message).ShowAsync();
}
}
}
For a project, we are migrating to Windows Azure. I have to make sure that the HTML to PDF converter will run on a 64 bit worker role.
Since Pechkin can't run as a 64bit application I have decided to use Tuespechkin, because they should be very alike and both use wkhtmltopdf to convert the HTML to PDF.
Now, i got this all set up but the resulting PDF is kind of disappointing.
Problems:
The font is rendered differently. With Pechkin the font is always 'sharp' where tuespechkin makes it very bold.
Results here:
http://postimg.org/image/xngqxryn1/
I tried using different fonts (even browser default). All render very bold
I tried using different Object- and Globalsettings (DPI, Outline, compression, name it; it never changes much).
All contents is selectable and copyable. I would like it to be more like an image (which is default in pechkin). Any advice on this would be appreciated.
Here is the code i am using to convert the HTML to PDF:
Pechkin, old:
var documentConfig = new ObjectConfig()
.SetAllowLocalContent(true)
.SetLoadImages(true)
.SetRunJavascript(true)
.SetPrintBackground(true)
.SetRenderDelay(15000);
var globalConfig = new GlobalConfig()
.SetMargins(new Margins(50, 50, 100, 100))
.SetDocumentTitle(company.Name)
.SetPaperSize(PaperKind.A4);
var pechkin = new SynchronizedPechkin(globalConfig);
var buffer = pechkin.Convert(documentConfig, parsedHtml);
Tuespechkin:
var converter = new ThreadSafeConverter(
//new ImageToolset(
new PdfToolset(
new Win64EmbeddedDeployment(
new TempFolderDeployment()
)
)
);
var documentConfig = new ObjectSettings {
WebSettings = new WebSettings {
EnableJavascript = true,
PrintBackground = true,
PrintMediaType = true
},
LoadSettings = new LoadSettings {
BlockLocalFileAccess = false,
RenderDelay = 15000,
},
HtmlText = parsedHtml
};
var globalConfig = new GlobalSettings();
globalConfig.Margins = new MarginSettings(2.645833333333, 1.322916666667, 2.645833333333, 1.322916666667);
globalConfig.Margins.Unit = Unit.Centimeters;
globalConfig.DocumentTitle = company.Name;
globalConfig.PaperSize = PaperKind.A4;
globalConfig.UseCompression = false;
globalConfig.DPI = 1200;
var doc = new HtmlToPdfDocument {
Objects = {
documentConfig
},
GlobalSettings = globalConfig
};
var buffer = converter.Convert(doc);
Any help on either problem would be much appreciated!
As you say, I can't solve the problem.
But IIS can be set to run 32-bit applications.
as this photo:
http://i.stack.imgur.com/6l6Es.png
So you can run Pechkin in you Azure.
You can see more in this.
https://codeutil.wordpress.com/2013/09/16/convert-html-to-pdf/