How to round image downloaded from web in blackberry cascades using qml - blackberry

I have a listview that displays a list of userdetails on right and profile pic on left which I get from back end. For downloading and loading the image I'm using a webviewsample image class from github and it works fine. Now I'm need to make the image round. As I searched through web I understand nine slicing is used to do this but I'm not sure how. Each of my listitem has a different background which changes randomly. Below are the sample image of what I have done and what I actually want.
This is my current list view
This is how I need it to be
This is the code of my custom list item that displays this view
Container {
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
Container {
id:profileSubContainer
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
layout: DockLayout {
}
WebImageView {
id: profilePic
url: profilePicture
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
scalingMethod: ScalingMethod.AspectFit
visible: (profilePic.loading == 1.0)
}
ImageView {
id: defaultPic
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
scalingMethod: ScalingMethod.AspectFit
imageSource: "asset:///Images/defaultProfile.png"
visible:!profilePic.visible
}
layoutProperties: StackLayoutProperties
{
spaceQuota: 1
}
}
CustomButtonTextArea {
id: userName
layoutProperties: StackLayoutProperties {
spaceQuota: 2
}
text: username
textEditable: false
textAreaStyle: getStyle()
}
}

If you have older version of Qt where this isn't supported directly, a rather hackish way to do is this :
Cut out a circular hole from the background image (Using Photoshop/GIMP etc.) and save it as a PNG.
Now all you need to do is to arrange all the elements in such a way that it appears as if the profile pic has been cut out. If you place your profile pic first and then the background image, background image cover the profile pic, leaving only circular part from it visible (Note that it SHOULD be PNG for this to work).
Correct order will be :
a. Profile Image
b. Background Image
c. Text
You can either write these elements in that order or use the z value of elements.
Image // Background Image
{
z = 2;
}
Image // Profile Image
{
z = 1;
}
Text
{
z = 3;
}
P.S. This is pseudo code, I hope you get the idea. I did something like this with qt 4.8 long back, and it worked liked a charm.
Edit 1.
In case you want to have background of random color instead of images (as you have asked in the comment), you can try to do this using Qt.
Create the custom background with using QPainter or some similar class and some clipping mask to carve out the circular part.
Expose this class as a Qml element.
Use it for your case by passing random colors while drawing.
They talk of something similar here : http://qt-project.org/forums/viewthread/2066
P.S. Haven't tried it myself, but looks like a good direction if you are stuck otherwise.

If you can't use OpacityMask because your version of Qt doesn't support QtGraphicalEffects, you could do the same trick with Canvas, that is supported since Qt 5.0.
Rectangle{
id: root
width: 400
height: 400
color: "gray"
property string imageUrl: "./rabbid.jpg"
Canvas{
anchors{
fill: parent
margins: 50
}
Component.onCompleted:{
loadImage(imageUrl); // Ready to be used in onPaint handler
}
onPaint:{
console.log("Painting...");
var context = getContext("2d");
context.save();
context.fillStyle = "black";
context.arc(width/2, height/2, width/2, height/2, width);
context.fill();
context.globalCompositeOperation = "source-in";
context.drawImage(root.imageUrl, 0, 0, width, height);
context.restore();
}
}
}
The result:
Since Context.globalCompositeOperation = "source-in" is set, context operations will be done inside previous drawings. Take a look to Context2D for more info, and here for a graphical explanation of composite operations.

Related

How to build an adaptive layout in Jetpack Compose

So I am trying to Follow this documentation to achieve something similar to this documentation, this is where the CardTitle moves and image; but the Title and Description on this documentation do not seem to be available on Cards now? I can not access that when I try to create a Card. Biggest issue Card does not have Description anymore, maybe this needs to be updated or how can I achieve this. I am trying to something similar to the image shown.
Code from the Documentation.
#Composable
fun Card(
imageUrl: String,
title: String,
description: String
) {
var showMore by remember { mutableStateOf(false) }
BoxWithConstraints {
if (maxWidth < 400.dp) {
Column {
Image(imageUrl)
Title(title)
}
} else {
Row {
Column {
Title(title)
Description(
description = description,
showMore = showMore,
onShowMoreToggled = { newValue ->
showMore = newValue
}
)
}
Image(imageUrl)
}
}
}
}
Biggest issue Card does not have Description anymore, maybe this needs
to be updated or how can I achieve this. I am trying to something
similar to the image shown.
This is not an issue because the sample above is for demonstrating flexible layout based on screen size using BoxWithConstraints. When you build your layouts you don't have follow this exact pattern.
You can do it in many ways including
Column {
Image(imageUrl)
Title(title)
// You can add a description that is one line with ellipsis overflow for instance. Or it's font size can be smaller than title
}
In your example demonstrator preferred to not show when screen size is less than 400.dp.
BoxWithConstraints is suitable for building a selective layouts based on max or min width/height from its Constraints

How can an effect find out the display size of the UIImageView it is attached to?

In Xamarin.Forms, an Effect can be attached to a View. In my case, the View is displaying an Image. And the effect is making a colored "glow" around the visible pixels of the image. XAML:
<Image Source="{Binding LogoImage}" ...>
<Image.Effects>
<effects:GlowEffect Radius="5" Color="White" />
</Image.Effects>
</Image>
The effect is implemented as a subclass of RoutingEffect:
public class GlowEffect : Xamarin.Forms.RoutingEffect
{
public GlowEffect() : base("Core.ImageGlowEffect")
{
}
...
}
On each platform, there is a PlatformEffect to implement the effect. For iOS:
using ...
[assembly: ExportEffect(typeof(Core.Effects.ImageGlowEffect), "ImageGlowEffect")]
namespace Core.Effects
{
public class ImageGlowEffect : PlatformEffect
{
protected override void OnAttached()
{
ApplyGlow();
}
protected override void OnElementPropertyChanged( PropertyChangedEventArgs e )
{
base.OnElementPropertyChanged( e );
if (e.PropertyName == "Source") {
ApplyGlow();
}
}
private void ApplyGlow()
{
var imageView = Control as UIImageView;
if (imageView.Image == null)
return;
var effect = (GlowEffect)Element.Effects.FirstOrDefault(e => e is GlowEffect);
if (effect != null) {
CGRect outSize = AVFoundation.AVUtilities.WithAspectRatio( new CGRect( new CGPoint(), imageView.Image.Size ), imageView.Frame.Size );
...
}
}
...
}
}
The above code works if Source is changed dynamically: at the time Source changes, the UIImageView (Bounds or Frame) has a size. BUT if the Source is set statically in XAML, that logic does not run: so the only call to ApplyGlow is during OnAttach. UNFORTUNATELY, during OnAttach, the UIImageView has size (0, 0).
How get this effect to work on iOS, with a static Source?
NOTE: The equivalent Android effect works via a handler attached to ImageView.ViewTreeObserver.PreDraw - at which time the size is known. So if there is an iOS equivalent event, that would be one way to solve.
More Details:
The original implementation used the original image size (imageView.Image.Size) - which is available during OnAttach. This can be made to "work", but is not satisfactory: the glow is applied to the full size image. If the image is significantly larger than the view area, the glow becomes much too small a radius (iOS shrinks the image+glow as it renders): it does not have the desired appearance.
ApplyGlow has an option to apply a tint color to the image. That tint color is different than the glow color. I mention this because it restricts the possible solutions: AFAIK, can't just set options on an image and let iOS figure out how to render it - need to explicitly resize the image and draw the resized tinted image on top of a blurred version (the glow). This code all works - if imageView.Bounds.Size (or imageView.Frame.Size) is available (and non-zero).
With a breakpoint in OnElementPropertyChanged, I've checked to see if imageView size is known for any property that is always set. No; if no properties are dynamically set, the property changes all occur before imageView has a size.
Maybe it's a workaround and I don't know if it is acceptable to you.
Add a little delay before calling ApplyGlow(); in OnAttached. After the delay, you will get the imageView.Frame.Size or imageView.Bounds.Size.
protected override async void OnAttached()
{
await Task.Delay(TimeSpan.FromSeconds(0.3));// it can be 0.2s,0.1s, depending on you
ApplyGlow();
}
And if you have set WidthRequest, HeightRequest, you can get there without the delay:
private void ApplyGlow()
{
var imageView = Control as UIImageView;
if (imageView.Image == null)
return;
Console.WriteLine(imageView.Image.Size.Width);
Console.WriteLine(imageView.Image.Size.Height);
CoreGraphics.CGSize rect = imageView.Bounds.Size;
CoreGraphics.CGSize rect2 = imageView.Frame.Size;
Console.WriteLine(rect);
Console.WriteLine(rect2);
double width = (double)Element.GetValue(VisualElement.WidthRequestProperty);
double height = (double)Element.GetValue(VisualElement.HeightRequestProperty);
Console.WriteLine(width);
Console.WriteLine(height);
double width2 = (double)Element.GetValue(VisualElement.WidthProperty);
double height2 = (double)Element.GetValue(VisualElement.HeightProperty);
Console.WriteLine(width2);
Console.WriteLine(height2);
}

Angular UI Grid - how to add an image to the top of the exported PDF?

I'm using Angular UI Grid and I've tried to few ways to add an image (logo) to the top of the PDF document which gets exported.
I've had no luck with the implementations I've tried...
exporterPdfHeader: { text: "My Header", image: "<urlOfImage>" }
exporterPdfHeader: { text: "My Header", backgroundImage: "<urlOfImage>" }
exporterPdfHeader: { text: "My Header", backgroundImage: url("<urlOfImage>") }
Is this even possible to do?
Thanks in advance.
Can you add your image inside a custom html header using headerTemplate: 'header-template.html', in grid-options?
See example ui-grid tutorial
edit
OK, having looked at the source and docs for the export, there is nothing there about passing images in the header.
It does refer you to pdfMake
Images
This is simple. Just use the { image: '...' } node type.
JPEG and PNG formats are supported.
var docDefinition = {
content: [
{ // you'll most often use dataURI images on the browser side // if no width/height/fit is provided, the original size will be used image: 'data:image/jpeg;base64,...encodedContent...' },
{ // if you specify width, image will scale proportionally image: 'data:image/jpeg;base64,...encodedContent...', width: 150 },
{ // if you specify both width and height - image will be stretched image: 'data:image/jpeg;base64,...encodedContent...', width: 150, height: 150 },
{ // you can also fit the image inside a rectangle image: 'data:image/jpeg;base64,...encodedContent...', fit: [100, 100] },
{ // if you reuse the same image in multiple nodes, // you should put it to to images dictionary and reference it by name image: 'mySuperImage' },
{ // under NodeJS (or in case you use virtual file system provided by pdfmake) // you can also pass file names here image: 'myImageDictionary/image1.jpg' } ],
images: {
mySuperImage: 'data:image/jpeg;base64,...content...' } }
end of quote
So it looks like you were close.
Can you try a relative path from the root of your website wrapped in single quotes.
Had to write a custom export function to add page margins.
Plnkr
$scope.export = function() {
var exportColumnHeaders = uiGridExporterService.getColumnHeaders($scope.gridApi.grid, uiGridExporterConstants.ALL);
var exportData = uiGridExporterService.getData($scope.gridApi.grid, uiGridExporterConstants.ALL, uiGridExporterConstants.ALL, true);
var docDefinition = uiGridExporterService.prepareAsPdf($scope.gridApi.grid, exportColumnHeaders, exportData);
docDefinition.pageMargins = [40, 80, 40, 60];
if (uiGridExporterService.isIE() || navigator.appVersion.indexOf("Edge") !== -1) {
uiGridExporterService.downloadPDF($scope.gridOptions.exporterPdfFilename, docDefinition);
} else {
pdfMake.createPdf(docDefinition).open();
}
}
Image has to be provided as base 64 encoded, unless using Node.js (as per pdfmake library).
Otherwise, you may need to use a JavaScript function to download and convert an image to base 64.
References:
https://stackoverflow.com/a/37058202/2808230
pdfExport function in http://ui-grid.info/release/ui-grid.js
Found this as I was writing up this answer: Angular UI Grid - Exporting an image to a pdf

Cocos2d-x how to create image button with title and font

Hi i am converting my game from Corona SDK to Cocos2d-x 3.0 alpha.
I need to create an image button with text on it. It was very simple in Corona SDK with widget.newButton, which takes all x, y, size, font, image etc in single function.
Now i couldn't find any alternate to this in Cocos2d-x. The closest thing i have found in it is MenuItemImage
auto closeItem = MenuItemImage::create(
"blank.png",
"blank-selected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/2 , origin.y + closeItem->getContentSize().height/2));
auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
It takes the images and event, but i cannot set title and font on it. Anyone has idea how to set title and font on it?
You can use MenuItemFont or MenuItemLabel.
For example:
MenuItemFont::setFontName( "Marker Felt" );
MenuItemFont::setFontSize( 34 );
auto label = LabelBMFont::create( "go back", "fonts/bitmapFontTest3.fnt" );
auto back = MenuItemLabel::create(label, CC_CALLBACK_1(MenuLayer4::backCallback, this) );
or
MenuItemFont::setFontSize( 34 );
MenuItemFont::setFontName("Marker Felt");
auto item6 = MenuItemFont::create("Bugs", CC_CALLBACK_1(MenuLayerMainMenu::menuCallbackBugsTest, this));
For more information, see MenuTest.ccp
update
You can simply new a Label, and add it to you MenuItemImage, such as:
LabelTTF* closeLabel = LabelTTF::create("close", "Marker Felt", 28);
closeItem->addChild(closeLabel);
And you may need to adjust the label's position.
It's fairly simple, this works in at least cocos2d-x 3.10 and 3.16, but if you're looking to make a button with cocos2d, use the built in cocos2d::ui namespace for Button.
cocos2d::ui::Button* button = cocos2d::ui::Button::create();
//button textures
button->loadTextures(
"<your default texture>.png",
"<your pressed texture>.png",
"<your disabled texture>.png",
cocos2d::ui::Widget::TextureResType::PLIST
);
//text content, font, and size
button->setTitleText("Touch me!");
button->setTitleFontName("arial");
button->setTitleFontSize(24.0f);
//bind a callback with a lambda
auto touch_handler = [](cocos2d::Ref* ref, cocos2d::ui::Widget::TouchEventType evt)
{
if (evt == cocos2d::ui::Widget::TouchEventType::ENDED)
{
//do your callback logic here, ie play a sound or vibrate
}
};
button->addTouchEventListener(touch_handler);
//then finally, like a Nodes, add it to your scene
my_scene->addChild(button);
The textures you'll load are ideally packed into a texture with something like TexturePacker, otherwise you'll change it to LOCAL instead of PLIST. The textures will be used when the button is default, or when there's a touch, or when the button is disabled.

kineticjs image backgrounds not transparent

I have some images that are .png's with transparent backgrounds however, when they are added to the stage they have white backgrounds. Am i missing a trick here?
Each image is added like so:
var layer = new Kinetic.Layer();
var book = new Image();
book.onload=function () {
bookImg = new Kinetic.Image ({ x: 885, y: 780, offset: [85.5, 106], image:book, name:book, opacity: 0, /*scale:{x:0.5, y:0.5}*/ });
layer.add(bookImg);
stage.add(layer);
}
book.src = "images/book.png";
is it that the layer itself is what's creating the white background?
a little confused!
Cant it be that you have to set the background to transparent? Not only the picture itself but the image-object containing the image. Maybe the layer aswell.
You shouldn't need to set the opacity on a Kinetic.Image() object. If you want it to be invisible, either initially or after being placed, simply use hide() (and subsequently show() to re-show it). Or set visible to false in the parameters. The minimum needed to place an image on the stage looks like this:
var image = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
width: 300,
height: 120
});
layer.add(image);
layer.draw();
This assumes your layer has already been added to a Kinetic.Stage() and the image has loaded ( imageObj.onload = function(){} ). Including a name is fine, the offset and opacity (and even scale) are valid key/value pairs for parameters but not really necessary when creating the image. These can always be set after the image has been added to the layer as well (using one of the many setters in the KineticJS library).
I'd try using a minimalist approach to see if the image shows up as intended first, then go from there.

Resources