QML changing size of image - image

I have an image object in QML (QtQuick 1.0), its height must be relative (in case of window scaling), but the problem is when I try to display this image in fullsize. Please look at the following part of my code:
Image {
id: selectionDialogImage
source: "qrc:/Images/myImage.png"
property int oldHeight: sourceSize.height
sourceSize.height: testsList.height/3
scale: 1
anchors.bottom: parent.bottom
anchors.left: parent.left
visible: false
property bool imageFullsize: false
MouseArea {
anchors.fill: parent
onClicked:
{
if(parent.imageFullsize)
{
parent.parent = selectionDialogQuestionText;
parent.sourceSize.width = undefined;
parent.sourceSize.height = testsList.height/3;
parent.anchors.horizontalCenter = undefined;
parent.anchors.verticalCenter = undefined;
parent.anchors.left = selectionDialogQuestionText.left;
parent.anchors.bottom = selectionDialogQuestionText.bottom;
parent.imageFullsize = false;
}
else
{
parent.parent = mainItem;
parent.sourceSize.height = parent.oldHeight;
//parent.sourceSize.height = undefined;
parent.sourceSize.width = mainItem.width;
parent.anchors.horizontalCenter = mainItem.horizontalCenter;
parent.imageFullsize = true;
}
}
}
}
selectionDialogQuestionText is a default parent of my image item. mainItem is the largest item, it has size of the whole window. So I want to have the image size set on the basis of width when I'm displaying it on a fullscreen, but in another state I want to scale the image setting its height.
When I set parent.sourceSize.width = mainItem.width;, image isn't scaled, but its height is as previous (very little) so its proportions are inappropriate.
Can I store old height of source image in any way? I need something like const, because property int oldHeight: sourceSize.heigh is relative. Or is there a way to restore default size of image and then set height/width?
UPDATE #1:
I tried to use method described by #Mitch:
property int oldHeight
Component.onCompleted: {
oldHeight = sourceSize.height
}
sourceSize.height: 250
but console.log("oldHeight="+parent.oldHeight) a few lines below shows oldHeight=250, not original height.

Can I store old height of source image in any way?
You can use Component.onCompleted:
Image {
// ...
Component.onCompleted: {
oldHeight = sourceSize.height
}
}

Related

Jcrop Image Intervention Laravel 5

i am using Image Intervention and jcrop to crop and resize image in laravel, but having problems. The issue which i think is that , when i save the file width and height is correct according to the selection, but the x & y is not correct, I am completely lost here, dont know what to do , Please help.
I have made but cropping area is wrong.
here is the code example.
// convert bytes into friendly format
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
}
// check for selected crop region
function checkForm() {
if (parseInt($('#w').val())) return true;
$('.setting-image-error').html('Select area').show();
return false;
}
// update info by cropping (onChange and onSelect events handler)
function updateInfo(e) {
$('#x1').val(e.x);
$('#y1').val(e.y);
$('#x2').val(e.x2);
$('#y2').val(e.y2);
$('#w').val(e.w);
$('#h').val(e.h);
}
// clear info by cropping (onRelease event handler)
function clearInfo() {
$('#w').val('');
$('#h').val('');
}
// Create variables (in this scope) to hold the Jcrop API and image size
var jcrop_api, boundx, boundy;
function fileSelectHandler() {
// get selected file
var oFile = $('#picture')[0].files[0];
// hide all errors
$('.setting-image-error').hide();
// check for image type (jpg and png are allowed)
var rFilter = /^(image\/jpeg|image\/png)$/i;
if (!rFilter.test(oFile.type)) {
$('.setting-image-error').html('Select only jpg, png').show();
return;
}
// check for file size
if (oFile.size > 10000000) {
$('.setting-image-error').html('Too Big file ').show();
return;
}
// preview element
var oImage = document.getElementById('preview');
// prepare HTML5 FileReader
var oReader = new FileReader();
oReader.onload = function (e) {
// e.target.result contains the DataURL which we can use as a source of the image
oImage.src = e.target.result;
oImage.onload = function () { // onload event handler
// display step 2
$('.setting-image-cropping-stage').fadeIn(500);
// display some basic image info
var sResultFileSize = bytesToSize(oFile.size);
$('#filesize').val(sResultFileSize);
$('#filetype').val(oFile.type);
$('#filedim').val(oImage.naturalWidth + ' x ' + oImage.naturalHeight);
// destroy Jcrop api if already initialized
if (typeof jcrop_api !== 'undefined') {
jcrop_api.destroy();
jcrop_api = null;
$('#preview').width(oImage.naturalWidth);
$('#preview').height(oImage.naturalHeight);
}
//Scroll the page to the cropping image div
$("html, body").animate({scrollTop: $(document).height()}, "slow");
// initialize Jcrop
$('#preview').Jcrop({
minSize: [32, 32], // min crop size
aspectRatio: 1, // keep aspect ratio 1:1
bgFade: true, // use fade effect
bgOpacity: .3, // fade opacity
onChange: updateInfo,
onSelect: updateInfo,
onRelease: clearInfo
}, function () {
// use the Jcrop API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the Jcrop API in the jcrop_api variable
jcrop_api = this;
});
}
}
// read selected file as DataURL
oReader.readAsDataURL(oFile);
}
and Controller code is below.
public function image_crop_resize_and_upload($file, $user_id,$width,$height,$x1,$y1)
{
$filename = $user_id . '.jpg';// image file name
$target_path = User::PICTURE_PATH . $filename;//path where to create picture with new dimensions
$img = \Image::make($file->getRealPath());// create the instance of image with the real path of the image
$filetype = $img->mime();//get file mime type
$filetypes = ['image/jpg', 'image/jpeg', 'image/png']; //allowed files types
//if file exists in the target folder, system will delete the file and next step will create new one.
if (File::exists($target_path)) {
File::delete($target_path);
}
if (in_array($filetype, $filetypes, true)) {
$img->crop($width, $height,$x1,$y1);
$img->encode('jpg', 85);
$img->resize($width,$height);
$img->save('uploads/' . $user_id . '.jpg');
return true;
} else {
return false;
}
}
When i have the file the file width and height is correct, but the selection area, x & y is not correct.
Yes , I have got the answer. The problem is very simple the x and y position of image are wrong because it is inside a bootstrap responsive class. the proper solution is just to remove the class . So the image actually dimension will be shown. and than select the are. Thats it.
<img id="preview" name="preview" class="img-responsive"/>
this should be
<img id="preview" name="preview"/>

Xamarin Forms vertical align image at bottom programmatically

In the (relatively) new Xamarin Forms I'm trying to vertically align an image to the bottom of a scrollview.
This is my code, this does exactly what I want (for larger images it scrolls). But when I have an image which is smaller than the height of the device, it should align to the bottom of the screen, instead of the center (probably default) of the screen. Since the documentation is (still) lacking, how can I achieve this in code?
return new ContentPage {
Content = new ScrollView {
Orientation = ScrollOrientation.Vertical,
BackgroundColor = Color.Black,
Content = new Image {
Source = ImageSource.FromFile (image)
}
}
};
I've tried it with this, but it gives an error that the call is ambiguous between the following methods or properties...
RelativeLayout rl = new RelativeLayout ();
rl.Children.Add (new ScrollView {
Orientation = ScrollOrientation.Vertical,
BackgroundColor = Color.Black,
Content = new Image {
Source = ImageSource.FromFile (image)
}
});
return new ContentPage {
Content = rl
};
From the Assembly Browser in Xamarin Studio, your options for Children.Add are:
void Add(T view, Expression<Func<Rectangle>> bounds);
void Add(T view, Expression<Func<double>> x = null, Expression<Func<double>> y = null, Expression<Func<double>> width = null, Expression<Func<double>> height = null);
void Add(T view, Constraint xConstraint = null, Constraint yConstraint = null, Constraint widthConstraint = null, Constraint heightConstraint = null);
Where Expression is the type from System.Linq.Expresssions.
You received an ambiguous call error because all these overloads have default values for all parameters besides view.
In order to use the object initializer for Children, you'll need to pass in your expressions or constraints like:
rl.Children.Add (
{
new ScrollView {
Orientation = ScrollOrientation.Vertical,
BackgroundColor = Color.Black,
Content = new Image {
Source = ImageSource.FromFile (image)
}
},
Constraint.Constant(0),
Constraint.Constant(0)
}
)
Constraint.RelativeToParent and Constraint.RelativeToView are useful in simple cases and Expression trees will solve arbitrary layout problems.

Flex - Easy way to set border on image

Is there an easy way to add a simple border to an image?
I'm loading in image thumbs, and would like to add a border at runtime, instead of having to edit all the thumbs.
I'm using Spark Image.
Thanks!
EDIT:
I need to add a 1 px white border around these thumbs. I set the size of the tumbs to be 90x90, to make them fit if they are either horisontal or vertical, but the actual images in my example scales down to 90x51 (this is not fixed, only 90x90 as a maximum is fixed)
This is my code for adding thumbNails to a TileGroup (loading the gallery from an xml file):
private function loadPopUpThumbs():void{
if(curThumbImg <= totThumbImg){
var thumbImg:Image = new Image();
var _loader:Loader = new Loader();
var imageNr:int = curThumbImg;
var thumbContainer:BorderContainer = new BorderContainer();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
thumbImg.source = e.currentTarget.content;
popUpImgGroup.addElement(thumbImg);
thumbImg.width = 90;
thumbImg.height = 90;
thumbImg.scaleMode = "letterbox";
thumbImg.verticalAlign = "bottom";
thumbImg.smooth = true;
thumbImg.id = "thumbImg" + imageNr;
//thumbImg.drawRoundRect(0,0,thumbImg.width,thumbImg.height, null, 0xffffff);
thumbImg.addEventListener(MouseEvent.CLICK, function(evt:MouseEvent):void{
popUpThumbClicked(imageNr.toString());
});
trace("Thumb added: " + popUpXMLList.(attribute('nr')==imageNr.toString()).#thumbURL);
curThumbImg++;
loadPopUpThumbs();
});
_loader.load(new URLRequest(encodeURI(popUpXMLList.(attribute('nr')==imageNr.toString()).#thumbURL)));
}else{
trace("DONE Adding thubs!!!");
}
}
Also: Would it be possible to add a linebreak in the items added to the TileGroup?
In my XML file I've defined a group attribute, so that I'm able to devide the images into groups. If I click a image from one group, I can skip next/prev within that group, but not to the next group. Is there any way for me to insert a linebreak to my TileGroup, so that I can listen for when the prevGroup != curGroup, and then add in some sort of spacing before continuing adding the next thumbs? All I need is a way to skip a line in the tileGroup :)
Thanks!
You can create new custom Image Class, extends spark Image. Very simple and clean. And set border size and color with css. See example:
package classes
{
import flash.display.CapsStyle;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import spark.components.Image;
public class ImageBorder extends Image
{
public function ImageBorder()
{
super();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (imageDisplay && imageDisplay.bitmapData)
{
var borderSize:Number = getStyle("borderSize") || 0;
var borderColor:Number = getStyle("borderColor") || 0xffffff;
var half:Number = borderSize/2;
imageDisplay.left = imageDisplay.top = imageDisplay.right = imageDisplay.bottom = borderSize;
graphics.clear();
graphics.lineStyle(borderSize, borderColor, 1, false, LineScaleMode.NONE, CapsStyle.NONE, JointStyle.MITER);
graphics.moveTo(0, half);
graphics.lineTo(unscaledWidth -half, half);
graphics.lineTo(unscaledWidth - half, unscaledHeight-half);
graphics.lineTo(half, unscaledHeight-half);
graphics.lineTo(half, half);
}
}
}
}
In application use with css:
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace classes "classes.*";
classes|ImageBorder
{
borderSize : 10;
borderColor : "0xff00ff";
}
</fx:Style>
<classes:ImageBorder source=" your source url " />
Spark image is a SkinnableComponent.
You can create your custom skin that supports borders in any
convenient way, like styles or properties.
Or you can set that
skin if you want to see border or remove it if you don't want
Or you can put it inside BorderContainer, and set borderVisible to
true when you want to see the border.

One vertical scroll bar for whole Dijit BorderContainer

Here is the structure of my HTML body.
<body class="claro">
<div id="BorderContainerMain" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design:'headline'" style="width: 100%; border:0; padding:0; margin:0;">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'top'" style="border: 0;">
<div id="topBanner" data-dojo-type="core.widget.GeneralMainHeader" ></div>
</div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'left'" style="border: 0;">
<div id="leftNav" data-dojo-type="core.widget.GeneralLeftNavigation"></div>
</div>
<div id="contentStackContainer" data-dojo-type="dijit.layout.StackContainer" data-dojo-props="region:'center', style: 'border: 0; padding: 0; margin: 0;'"></div>
</div>
Now, my desire is to make the whole screen auto grow in height depending on the content of the center region and let the viewport handle the vertical scrolling.
I am fairly new into dijit layout and I am using DOJO 1.6. I have already learned that I have to write code to achieve this. So, I am trying to get some experience guidance on this.
Thanks,
Rishi
So, I wrote up a custom resize for my purpose but it is not working. Is there any why it not working. Here is the code:
dojo.provide("core.widget.ClientBorderContainer");
dojo.require("dijit.layout.BorderContainer");
dojo.declare("core.widget.ClientBorderContainer", [dijit.layout.BorderContainer], {
totalHeight: 0,
_setupChild: function(/*dijit._Widget*/ child){
// Override BorderContainer._setupChild().
var region = child.region;
console.debug("region :: "+region);
if(region){
this.inherited(arguments);
dojo.addClass(child.domNode, this.baseClass+"Pane");
var ltr = this.isLeftToRight();
if(region == "leading"){ region = ltr ? "left" : "right"; }
if(region == "trailing"){ region = ltr ? "right" : "left"; }
// Create draggable splitter for resizing pane,
// or alternately if splitter=false but BorderContainer.gutters=true then
// insert dummy div just for spacing
if(region != "center" && (child.splitter || this.gutters) && !child._splitterWidget){
var _Splitter = dojo.getObject(child.splitter ? this._splitterClass : "dijit.layout._Gutter");
var splitter = new _Splitter({
id: child.id + "_splitter",
container: this,
child: child,
region: region,
live: this.liveSplitters
});
splitter.isSplitter = true;
child._splitterWidget = splitter;
dojo.place(splitter.domNode, child.domNode, "after");
// Splitters aren't added as Contained children, so we need to call startup explicitly
splitter.startup();
console.debug("Should not be printed as there is no splitter");
}
child.region = region; // TODO: technically wrong since it overwrites "trailing" with "left" etc.
}
},
resize: function(newSize, currentSize){
// Overrides BorderContainer.resize().
// resetting potential padding to 0px to provide support for 100% width/height + padding
// TODO: this hack doesn't respect the box model and is a temporary fix
if(!this.cs || !this.pe){
var node = this.domNode;
this.cs = dojo.getComputedStyle(node);
this.pe = dojo._getPadExtents(node, this.cs);
this.pe.r = dojo._toPixelValue(node, this.cs.paddingRight);
this.pe.b = dojo._toPixelValue(node, this.cs.paddingBottom);
dojo.style(node, "padding", "0px");
}
//Following section calculates the desired height of the BorderContainer
console.debug(this.id+" contentBox height ::: "+dojo.contentBox(this.domNode).h);
this.totalHeight = 0;
dojo.forEach(this.getChildren(), this.calculateHeight, this);
console.debug("this.totalHeight ::: "+this.totalHeight);
console.debug("newSize "+newSize);
console.debug("currentSize "+currentSize);
////////////////////////////////////////////////
// summary:
// Call this to resize a widget, or after its size has changed.
// description:
// Change size mode:
// When changeSize is specified, changes the marginBox of this widget
// and forces it to relayout its contents accordingly.
// changeSize may specify height, width, or both.
//
// If resultSize is specified it indicates the size the widget will
// become after changeSize has been applied.
//
// Notification mode:
// When changeSize is null, indicates that the caller has already changed
// the size of the widget, or perhaps it changed because the browser
// window was resized. Tells widget to relayout its contents accordingly.
//
// If resultSize is also specified it indicates the size the widget has
// become.
//
// In either mode, this method also:
// 1. Sets this._borderBox and this._contentBox to the new size of
// the widget. Queries the current domNode size if necessary.
// 2. Calls layout() to resize contents (and maybe adjust child widgets).
//
// changeSize: Object?
// Sets the widget to this margin-box size and position.
// May include any/all of the following properties:
// | {w: int, h: int, l: int, t: int}
//
// resultSize: Object?
// The margin-box size of this widget after applying changeSize (if
// changeSize is specified). If caller knows this size and
// passes it in, we don't need to query the browser to get the size.
// | {w: int, h: int}
var node = this.domNode;
// set margin box size, unless it wasn't specified, in which case use current size
if(newSize){
dojo.marginBox(node, newSize);
// set offset of the node
if(newSize.t){ node.style.top = newSize.t + "px"; }
if(newSize.l){ node.style.left = newSize.l + "px"; }
}
// If either height or width wasn't specified by the user, then query node for it.
// But note that setting the margin box and then immediately querying dimensions may return
// inaccurate results, so try not to depend on it.
var mb = currentSize || {};
dojo.mixin(mb, {h: this.totalHeight}); // calculated height overrides currentSize
if( !("h" in mb) || !("w" in mb) ){
mb = dojo.mixin(dojo.marginBox(node), mb); // just use dojo.marginBox() to fill in missing values
}
// Compute and save the size of my border box and content box
// (w/out calling dojo.contentBox() since that may fail if size was recently set)
var cs = dojo.getComputedStyle(node);
var me = dojo._getMarginExtents(node, cs);
var be = dojo._getBorderExtents(node, cs);
console.debug("mb.w "+mb.w);
console.debug("mb.h "+mb.h);
var bb = (this._borderBox = {
w: mb.w - (me.w + be.w),
h: mb.h - (me.h + be.h)
});
var pe = dojo._getPadExtents(node, cs);
console.debug("bb.w "+bb.w);
console.debug("bb.h "+bb.h);
this._contentBox = {
l: dojo._toPixelValue(node, cs.paddingLeft),
t: dojo._toPixelValue(node, cs.paddingTop),
w: bb.w - pe.w,
h: bb.h - pe.h
};
// Callback for widget to adjust size of its children
this.layout();
///////////////////////////////////////////////
console.debug(this.id+" contentBox height ::: "+dojo.contentBox(this.domNode).h);
},
calculateHeight: function(/*dijit._Widget*/ child){
var region = child.region;
console.debug("region :: "+region);
if(region && (region == "top" || region == "center" || region == "bottom")){
var childHeight = 0;
if(child instanceof dijit.layout.StackContainer){
console.debug("selectedChildWidget "+child.selectedChildWidget);
if(child.selectedChildWidget)
childHeight = dojo.contentBox(child.selectedChildWidget.domNode).h;
else
childHeight = dojo.contentBox(child.domNode).h;
}else{
childHeight = dojo.contentBox(child.domNode).h;
}
this.totalHeight = this.totalHeight+childHeight;
console.debug("childHeight = "+childHeight+" child.declaredClass"+child.declaredClass);
}
},
_layoutChildren: function(/*String?*/ changedChildId, /*Number?*/ changedChildSize){
// summary:
// This is the main routine for setting size/position of each child.
// description:
// With no arguments, measures the height of top/bottom panes, the width
// of left/right panes, and then sizes all panes accordingly.
//
// With changedRegion specified (as "left", "top", "bottom", or "right"),
// it changes that region's width/height to changedRegionSize and
// then resizes other regions that were affected.
// changedChildId:
// Id of the child which should be resized because splitter was dragged.
// changedChildSize:
// The new width/height (in pixels) to make specified child
if(!this._borderBox || !this._borderBox.h){
// We are currently hidden, or we haven't been sized by our parent yet.
// Abort. Someone will resize us later.
return;
}
console.debug("custom lay out children called");
// Generate list of wrappers of my children in the order that I want layoutChildren()
// to process them (i.e. from the outside to the inside)
var wrappers = dojo.map(this.getChildren(), function(child, idx){
return {
pane: child,
weight: [
child.region == "center" ? Infinity : 0,
child.layoutPriority,
(this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1),
idx
]
};
}, this);
wrappers.sort(function(a, b){
var aw = a.weight, bw = b.weight;
for(var i=0; i<aw.length; i++){
if(aw[i] != bw[i]){
return aw[i] - bw[i];
}
}
return 0;
});
// Make new list, combining the externally specified children with splitters and gutters
var childrenAndSplitters = [];
dojo.forEach(wrappers, function(wrapper){
var pane = wrapper.pane;
childrenAndSplitters.push(pane);
if(pane._splitterWidget){
childrenAndSplitters.push(pane._splitterWidget);
}
});
// Compute the box in which to lay out my children
console.debug("this._borderBox.h :: "+this._borderBox.h);
var dim = {
l: this.pe.l,
t: this.pe.t,
w: this._borderBox.w - this.pe.w,
h: this._borderBox.h - this.pe.h
};
// Layout the children, possibly changing size due to a splitter drag
dijit.layout.layoutChildren(this.domNode, dim, childrenAndSplitters,
changedChildId, changedChildSize);
}
});
BorderContainer was written to take a sized box and calculate the center based on what's left over, sort of the opposite of what you're trying to do. AFAIK it won't support this.

Get scaled image dimensions for spark image

Is there an equivalent to contentWidth and contentHeight for spark images?
I can get the size of the image component itself, as well as the sourceWidth and sourceHeight properties to get the unscaled size of the image.
But I can't work out the scaled image width and height of the source as displayed in the image component.
Any help greatly appreciated.
Was just trying to solve this exact issue. An adequate solution I found was to use IMAGE_ID.transform.pixelBounds.height (or width). Note that this won't be set until after the updateComplete event fires for the image. No idea why FLEX doesn't have a simple scaledWidth property.
Try extending the Spark Image component to include 2 new read-only properties to provide the scaled width and height as an equivalent to contentWidth and contentHeight.
The following will create 2 new bindable properties to return the actual scaled width and height of the image displayed inside the Spark Image component.
/**
* Returns the width of the image display taking into account the actual
* constraints of the container. If no scaling has occurred the actual
* width of the control is returned.
*/
[Bindable(event="scaledWidthChanged")]
public function get scaledWidth():Number
{
var num:Number = this.width;
if (scaleMode == "letterbox")
{
try
{
if ( (width > 0) && (sourceWidth < sourceHeight) )
{
num = (sourceWidth/sourceHeight) * width;
}
}
catch(e:Error)
{
num = this.width;
}
}
return num;
}
/**
* Returns the height of the image display taking into account the actual
* constraints of the container. If no scaling has occurred the actual
* height of the control is returned.
*/
[Bindable(event="scaledHeightChanged")]
public function get scaledHeight():Number
{
var num:Number = this.width;
if (scaleMode == "letterbox")
{
try
{
if ((height > 0) && (sourceHeight < sourceWidth))
{
num = (sourceHeight/sourceWidth) * height;
}
}
catch(e:Error)
{
num = this.height;
}
}
return num;
}

Resources