[NUI] Fix unmatched return values before LazyUpdate (#3937)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / ImageView.cs
index dfee29d..44ea173 100755 (executable)
@@ -27,247 +27,25 @@ namespace Tizen.NUI.BaseComponents
     /// An instance of ImageView can be created using a URL or an image instance.<br />
     /// </summary>
     /// <since_tizen> 3 </since_tizen>
-    public class ImageView : View
+    public partial class ImageView : View
     {
         static ImageView() { }
 
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty ResourceUrlProperty = BindableProperty.Create(nameof(ImageView.ResourceUrl), typeof(string), typeof(ImageView), string.Empty, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            string url = (string)newValue;
-            url = (url == null ? "" : url);
-            if (imageView.IsCreateByXaml && url.Contains("*Resource*"))
-            {
-                string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
-                url = url.Replace("*Resource*", resource);
-            }
-            imageView._resourceUrl = url;
-            imageView.UpdateImage(ImageVisualProperty.URL, new PropertyValue(url));
-        },
-        defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            string ret = "";
-
-            PropertyMap imageMap = new PropertyMap();
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
-            imageMap.Find(ImageVisualProperty.URL)?.Get(out ret);
-            return ret;
-        }));
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty ImageProperty = BindableProperty.Create(nameof(ImageView.Image), typeof(PropertyMap), typeof(ImageView), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                PropertyMap map = (PropertyMap)newValue;
-                if (imageView.IsCreateByXaml)
-                {
-                    string url = "", alphaMaskURL = "", auxiliaryImageURL = "";
-                    string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
-                    PropertyValue urlValue = map.Find(NDalic.ImageVisualUrl);
-                    bool ret = false;
-                    if (urlValue != null) ret = urlValue.Get(out url);
-                    PropertyMap mmap = new PropertyMap();
-                    if (ret && url.Contains("*Resource*"))
-                    {
-                        url = url.Replace("*Resource*", resource);
-                        mmap.Insert(NDalic.ImageVisualUrl, new PropertyValue(url));
-                    }
-
-                    ret = false;
-                    PropertyValue alphaMaskUrlValue = map.Find(NDalic.ImageVisualAlphaMaskUrl);
-                    if (alphaMaskUrlValue != null) ret = alphaMaskUrlValue.Get(out alphaMaskURL);
-                    if (ret && alphaMaskURL.Contains("*Resource*"))
-                    {
-                        alphaMaskURL = alphaMaskURL.Replace("*Resource*", resource);
-                        mmap.Insert(NDalic.ImageVisualUrl, new PropertyValue(alphaMaskURL));
-                    }
-
-                    ret = false;
-                    PropertyValue auxiliaryImageURLValue = map.Find(NDalic.ImageVisualAuxiliaryImageUrl);
-                    if (auxiliaryImageURLValue != null) ret = auxiliaryImageURLValue.Get(out auxiliaryImageURL);
-                    if (ret && auxiliaryImageURL.Contains("*Resource*"))
-                    {
-                        auxiliaryImageURL = auxiliaryImageURL.Replace("*Resource*", resource);
-                        mmap.Insert(NDalic.ImageVisualAuxiliaryImageUrl, new PropertyValue(auxiliaryImageURL));
-                    }
-
-                    map.Merge(mmap);
-                }
-                if (imageView._border == null)
-                {
-                    Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE, new Tizen.NUI.PropertyValue(map));
-                }
-            }
-        }),
-        defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (imageView._border == null)
-            {
-                PropertyMap temp = new PropertyMap();
-                Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(temp);
-                return temp;
-            }
-            else
-            {
-                return null;
-            }
-        }));
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty PreMultipliedAlphaProperty = BindableProperty.Create(nameof(PreMultipliedAlpha), typeof(bool), typeof(ImageView), false, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PreMultipliedAlpha, new Tizen.NUI.PropertyValue((bool)newValue));
-            }
-        }),
-        defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            bool temp = false;
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PreMultipliedAlpha).Get(out temp);
-            return temp;
-        }));
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty PixelAreaProperty = BindableProperty.Create(nameof(PixelArea), typeof(RelativeVector4), typeof(ImageView), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                Tizen.NUI.Object.SetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PixelArea, new Tizen.NUI.PropertyValue((RelativeVector4)newValue));
-            }
-        }),
-        defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            Vector4 temp = new Vector4(0.0f, 0.0f, 0.0f, 0.0f);
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.PixelArea).Get(temp);
-            RelativeVector4 relativeTemp = new RelativeVector4(temp.X, temp.Y, temp.Z, temp.W);
-            return relativeTemp;
-        }));
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty BorderProperty = BindableProperty.Create(nameof(Border), typeof(Rectangle), typeof(ImageView), null, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                imageView._border = new Rectangle((Rectangle)newValue);
-                imageView.UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(imageView._border));
-            }
-        },
-        defaultValueCreator: (bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            return imageView._border;
-        });
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty BorderOnlyProperty = BindableProperty.Create(nameof(BorderOnly), typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                imageView.UpdateImage(NpatchImageVisualProperty.BorderOnly, new PropertyValue((bool)newValue));
-            }
-        },
-        defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            bool ret = false;
-            PropertyMap imageMap = new PropertyMap();
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
-            imageMap.Find(ImageVisualProperty.BorderOnly)?.Get(out ret);
-            return ret;
-        }));
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty SynchronosLoadingProperty = BindableProperty.Create(nameof(SynchronosLoading), typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                imageView._synchronosLoading = (bool)newValue;
-                imageView.UpdateImage(NpatchImageVisualProperty.SynchronousLoading, new PropertyValue((bool)newValue));
-            }
-        },
-        defaultValueCreator: (bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            return imageView._synchronosLoading;
-        });
-
-        /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
-        [EditorBrowsable(EditorBrowsableState.Never)]
-        public static readonly BindableProperty OrientationCorrectionProperty = BindableProperty.Create(nameof(OrientationCorrection), typeof(bool), typeof(ImageView), false, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            if (newValue != null)
-            {
-                imageView.UpdateImage(ImageVisualProperty.OrientationCorrection, new PropertyValue((bool)newValue));
-            }
-        },
-        defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-
-            bool ret = false;
-            PropertyMap imageMap = new PropertyMap();
-            Tizen.NUI.Object.GetProperty((HandleRef)imageView.SwigCPtr, ImageView.Property.IMAGE).Get(imageMap);
-            imageMap?.Find(ImageVisualProperty.OrientationCorrection)?.Get(out ret);
-
-            return ret;
-        }));
-
-        internal static readonly BindableProperty ResourceUrlSelectorProperty = BindableProperty.Create("ResourceUrlSelector", typeof(Selector<string>), typeof(ImageView), null, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            imageView.resourceUrlSelector.Update(imageView, (Selector<string>)newValue, true);
-        },
-        defaultValueCreator: (bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            return imageView.resourceUrlSelector.Get(imageView);
-        });
-
-        internal static readonly BindableProperty BorderSelectorProperty = BindableProperty.Create("BorderSelector", typeof(Selector<Rectangle>), typeof(ImageView), null, propertyChanged: (bindable, oldValue, newValue) =>
-        {
-            var imageView = (ImageView)bindable;
-            imageView.borderSelector.Update(imageView, (Selector<Rectangle>)newValue, true);
-        },
-        defaultValueCreator: (bindable) =>
-        {
-            var imageView = (ImageView)bindable;
-            return imageView.borderSelector.Get(imageView);
-        });
-
         private EventHandler<ResourceReadyEventArgs> _resourceReadyEventHandler;
         private ResourceReadyEventCallbackType _resourceReadyEventCallback;
         private EventHandler<ResourceLoadedEventArgs> _resourceLoadedEventHandler;
         private _resourceLoadedCallbackType _resourceLoadedCallback;
 
+        // Collection of image-sensitive properties.
+        private bool _imagePropertyUpdatedFlag = false;
+        private bool _imagePropertyUpdateProcessAttachedFlag = false;
+        private PropertyMap _imagePropertyMap;
         private Rectangle _border;
         private string _resourceUrl = "";
-        private bool _synchronosLoading = false;
-        private string _alphaMaskUrl = null;
         private int _desired_width = -1;
         private int _desired_height = -1;
-        private readonly TriggerableSelector<string> resourceUrlSelector = new TriggerableSelector<string>(ResourceUrlProperty);
-        private readonly TriggerableSelector<Rectangle> borderSelector = new TriggerableSelector<Rectangle>(BorderProperty);
+        private TriggerableSelector<string> resourceUrlSelector;
+        private TriggerableSelector<Rectangle> borderSelector;
 
         /// <summary>
         /// Creates an initialized ImageView.
@@ -453,7 +231,6 @@ namespace Tizen.NUI.BaseComponents
             set
             {
                 SetValue(ResourceUrlProperty, value);
-                resourceUrlSelector.UpdateIfNeeds(this, value);
                 NotifyPropertyChanged();
             }
         }
@@ -469,8 +246,22 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return GetValue(ImageMapProperty) as PropertyMap;
+            }
+            set
+            {
+                SetValue(ImageMapProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private PropertyMap InternalImageMap
+        {
+            get
+            {
                 if (_border == null)
                 {
+                    // Get current properties force.
+                    // TODO: Need to make some flag that we only need cached property map.
                     PropertyMap returnValue = new PropertyMap();
                     PropertyValue image = GetProperty(ImageView.Property.IMAGE);
                     image?.Get(returnValue);
@@ -488,6 +279,14 @@ namespace Tizen.NUI.BaseComponents
                 {
                     PropertyValue setValue = new Tizen.NUI.PropertyValue(value);
                     SetProperty(ImageView.Property.IMAGE, setValue);
+                    // Image properties are changed hardly. We should ignore lazy UpdateImage
+                    _imagePropertyUpdatedFlag = false;
+                    _imagePropertyMap?.Dispose();
+                    _imagePropertyMap = null;
+                    if(value != null)
+                    {
+                        _imagePropertyMap = new PropertyMap(value);
+                    }
                     NotifyPropertyChanged();
                     setValue?.Dispose();
                 }
@@ -495,8 +294,24 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
-        /// ImageView Image, type PropertyMap
+        /// ImageView Image, type PropertyMap: string if it is a URL, map otherwise.
         /// </summary>
+        /// <remarks>
+        /// This PropertyMap use a <see cref="ImageVisualProperty"/>. <br />
+        /// See <see cref="ImageVisualProperty"/> for a detailed description. <br />
+        /// you can also use <see cref="Visual.Property"/>. <br />
+        /// See <see cref="Visual.Property"/> for a detailed description. <br />
+        /// </remarks>
+        /// <example>
+        /// The following example demonstrates how to use the Image property.
+        /// <code>
+        /// PropertyMap map = new PropertyMap();
+        /// map.Insert(Visual.Property.Type, new PropertyValue((int)Visual.Type.Image));
+        /// map.Insert(ImageVisualProperty.AlphaMaskURL, new PropertyValue(url));
+        /// map.Insert(ImageVisualProperty.FittingMode, new PropertyValue((int)FittingModeType.ScaleToFill);
+        /// imageview.Image = map;
+        /// </code>
+        /// </example>
         /// <since_tizen> 4 </since_tizen>
         public PropertyMap Image
         {
@@ -588,7 +403,6 @@ namespace Tizen.NUI.BaseComponents
             set
             {
                 SetValue(BorderProperty, value);
-                borderSelector.UpdateIfNeeds(this, value);
                 NotifyPropertyChanged();
             }
         }
@@ -614,18 +428,40 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
-        /// Gets or sets whether to synchronos loading the resourceurl of image.<br />
+        /// Gets or sets whether to synchronous loading the resourceurl of image.<br />
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
+        [Obsolete("Deprecated since API level 9 and will be removed in API level 11. Please use SynchronousLoading instead!")]
         public bool SynchronosLoading
         {
             get
             {
-                return (bool)GetValue(SynchronosLoadingProperty);
+                return SynchronousLoading;
+            }
+            set
+            {
+                SynchronousLoading = value;
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets whether the image of the ResourceUrl property will be loaded synchronously.<br />
+        /// </summary>
+        /// <remarks>
+        /// Changing this property make this ImageView load image synchronously at the next loading
+        /// by following operation: <see cref="Reload"/>, <see cref="SetImage(string)"/>,
+        /// and by some properties those cause reloading: <see cref="ResourceUrl"/>, <see cref="PreMultipliedAlpha"/> and etc.
+        /// </remarks>
+        /// <since_tizen> 9 </since_tizen>
+        public bool SynchronousLoading
+        {
+            get
+            {
+                return (bool)GetValue(SynchronousLoadingProperty);
             }
             set
             {
-                SetValue(SynchronosLoadingProperty, value);
+                SetValue(SynchronousLoadingProperty, value);
                 NotifyPropertyChanged();
             }
         }
@@ -729,7 +565,7 @@ namespace Tizen.NUI.BaseComponents
         public void Reload()
         {
             PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionReload, attributes);
+            this.DoAction(ImageView.Property.IMAGE, ActionReload, attributes);
             attributes?.Dispose();
         }
 
@@ -740,7 +576,7 @@ namespace Tizen.NUI.BaseComponents
         public void Play()
         {
             PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionPlay, attributes);
+            this.DoAction(ImageView.Property.IMAGE, ActionPlay, attributes);
             attributes?.Dispose();
         }
 
@@ -751,7 +587,7 @@ namespace Tizen.NUI.BaseComponents
         public void Pause()
         {
             PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionPause, attributes);
+            this.DoAction(ImageView.Property.IMAGE, ActionPause, attributes);
             attributes?.Dispose();
         }
 
@@ -762,7 +598,7 @@ namespace Tizen.NUI.BaseComponents
         public void Stop()
         {
             PropertyValue attributes = new PropertyValue(0);
-            this.DoAction(ImageView.Property.IMAGE, Property.ActionStop, attributes);
+            this.DoAction(ImageView.Property.IMAGE, ActionStop, attributes);
             attributes?.Dispose();
         }
 
@@ -776,31 +612,40 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return GetValue(AlphaMaskURLProperty) as string;
+            }
+            set
+            {
+                SetValue(AlphaMaskURLProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        private string InternalAlphaMaskURL
+        {
+            get
+            {
                 string ret = "";
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue maskUrl = imageMap?.Find(ImageVisualProperty.AlphaMaskURL);
-                maskUrl?.Get(out ret);
-                _alphaMaskUrl = ret;
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue maskUrl = _imagePropertyMap?.Find(ImageVisualProperty.AlphaMaskURL);
+                maskUrl?.Get(out ret);
                 maskUrl?.Dispose();
 
                 return ret;
             }
             set
             {
-                if (value == null)
+                PropertyValue setValue = new PropertyValue(value ?? "");
+                UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
+                // When we never set CropToMask property before, we should set default value as true.
+                using(PropertyValue cropToMask = _imagePropertyMap?.Find(ImageVisualProperty.CropToMask))
                 {
-                    value = "";
+                    if(cropToMask == null)
+                    {
+                        using PropertyValue setCropValue = new PropertyValue(true);
+                        UpdateImage(ImageVisualProperty.CropToMask, setCropValue);
+                    }
                 }
-
-                _alphaMaskUrl = value;
-
-                PropertyValue setValue = new PropertyValue(value);
-                UpdateImage(ImageVisualProperty.AlphaMaskURL, setValue);
                 setValue?.Dispose();
             }
         }
@@ -814,16 +659,23 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return (bool)GetValue(CropToMaskProperty);
+            }
+            set
+            {
+                SetValue(CropToMaskProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private bool InternalCropToMask
+        {
+            get
+            {
                 bool ret = false;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue cropUrl = imageMap?.Find(ImageVisualProperty.CropToMask);
-                cropUrl?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
-                cropUrl?.Dispose();
+                PropertyValue cropToMask = _imagePropertyMap?.Find(ImageVisualProperty.CropToMask);
+                cropToMask?.Get(out ret);
+                cropToMask?.Dispose();
 
                 return ret;
             }
@@ -831,11 +683,37 @@ namespace Tizen.NUI.BaseComponents
             {
                 PropertyValue setValue = new PropertyValue(value);
                 UpdateImage(ImageVisualProperty.CropToMask, setValue);
-                setValue.Dispose();
+                setValue?.Dispose();
             }
         }
 
-        internal VisualFittingModeType CovertFittingModetoVisualFittingMode(FittingModeType value)
+        /// <summary>
+        /// Actions property value for Reload image.
+        /// </summary>
+        private int ActionReload { get; set; } = Interop.ImageView.ImageVisualActionReloadGet();
+
+        /// <summary>
+        /// Actions property value to Play animated images.
+        /// This property can be redefined by child class if it use different value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected int ActionPlay { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionPlayGet();
+
+        /// <summary>
+        /// Actions property value to Pause animated images.
+        /// This property can be redefined by child class if it use different value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected int ActionPause { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionPauseGet();
+
+        /// <summary>
+        /// Actions property value to Stop animated images.
+        /// This property can be redefined by child class if it use different value.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected int ActionStop { get; set; } = Interop.AnimatedImageView.AnimatedImageVisualActionStopGet();
+
+        internal VisualFittingModeType ConvertFittingModetoVisualFittingMode(FittingModeType value)
         {
             switch (value)
             {
@@ -850,7 +728,7 @@ namespace Tizen.NUI.BaseComponents
                 case FittingModeType.FitHeight:
                     return VisualFittingModeType.FitHeight;
                 case FittingModeType.FitWidth:
-                    return VisualFittingModeType.FitHeight;
+                    return VisualFittingModeType.FitWidth;
                 default:
                     return VisualFittingModeType.Fill;
             }
@@ -877,6 +755,11 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
+        internal override LayoutItem CreateDefaultLayout()
+        {
+            return new ImageLayout();
+        }
+
         /// <summary>
         /// Gets or sets fitting options used when resizing images to fit.<br />
         /// If not supplied, the default is FittingModeType.Fill.<br />
@@ -889,22 +772,30 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return (FittingModeType)GetValue(FittingModeProperty);
+            }
+            set
+            {
+                SetValue(FittingModeProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        private FittingModeType InternalFittingMode
+        {
+            get
+            {
                 int ret = (int)VisualFittingModeType.Fill;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue fittingMode = imageMap?.Find(Visual.Property.VisualFittingMode);
-                fittingMode?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue fittingMode = _imagePropertyMap?.Find(Visual.Property.VisualFittingMode);
+                fittingMode?.Get(out ret);
                 fittingMode?.Dispose();
 
                 return ConvertVisualFittingModetoFittingMode((VisualFittingModeType)ret);
             }
             set
             {
-                VisualFittingModeType ret = CovertFittingModetoVisualFittingMode(value);
+                VisualFittingModeType ret = ConvertFittingModetoVisualFittingMode(value);
                 PropertyValue setValue = new PropertyValue((int)ret);
                 UpdateImage(Visual.Property.VisualFittingMode, setValue);
                 setValue?.Dispose();
@@ -925,15 +816,26 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue desireWidth = imageMap?.Find(ImageVisualProperty.DesiredWidth);
-                desireWidth?.Get(out _desired_width);
-
-                imageMap?.Dispose();
-                image?.Dispose();
-                desireWidth?.Dispose();
+                return (int)GetValue(DesiredWidthProperty);
+            }
+            set
+            {
+                SetValue(DesiredWidthProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private int InternalDesiredWidth
+        {
+            get
+            {
+                // Sync as current properties only if both _desired_width and _desired_height are setuped.
+                if(_desired_width != -1 && _desired_height != -1)
+                {
+                    UpdateImage();
+                }
+                PropertyValue desirewidth = _imagePropertyMap?.Find(ImageVisualProperty.DesiredWidth);
+                desirewidth?.Get(out _desired_width);
+                desirewidth?.Dispose();
 
                 return _desired_width;
             }
@@ -942,7 +844,9 @@ namespace Tizen.NUI.BaseComponents
                 if (_desired_width != value)
                 {
                     _desired_width = value;
-                    UpdateImage(0, null);
+                    PropertyValue setValue = new PropertyValue(value);
+                    UpdateImage(ImageVisualProperty.DesiredWidth, setValue);
+                    setValue?.Dispose();
                 }
             }
         }
@@ -959,14 +863,25 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue desireheight = imageMap?.Find(ImageVisualProperty.DesiredHeight);
+                return (int)GetValue(DesiredHeightProperty);
+            }
+            set
+            {
+                SetValue(DesiredHeightProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private int InternalDesiredHeight
+        {
+            get
+            {
+                // Sync as current properties only if both _desired_width and _desired_height are setuped.
+                if(_desired_width != -1 && _desired_height != -1)
+                {
+                    UpdateImage();
+                }
+                PropertyValue desireheight = _imagePropertyMap?.Find(ImageVisualProperty.DesiredHeight);
                 desireheight?.Get(out _desired_height);
-
-                imageMap?.Dispose();
-                image?.Dispose();
                 desireheight?.Dispose();
 
                 return _desired_height;
@@ -976,7 +891,9 @@ namespace Tizen.NUI.BaseComponents
                 if (_desired_height != value)
                 {
                     _desired_height = value;
-                    UpdateImage(0, null);
+                    PropertyValue setValue = new PropertyValue(value);
+                    UpdateImage(ImageVisualProperty.DesiredHeight, setValue);
+                    setValue?.Dispose();
                 }
             }
         }
@@ -990,15 +907,23 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return (ReleasePolicyType)GetValue(ReleasePolicyProperty);
+            }
+            set
+            {
+                SetValue(ReleasePolicyProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        
+        private ReleasePolicyType InternalReleasePolicy
+        {
+            get
+            {
                 int ret = (int)ReleasePolicyType.Detached;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue releasePoli = imageMap?.Find(ImageVisualProperty.ReleasePolicy);
-                releasePoli?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue releasePoli = _imagePropertyMap?.Find(ImageVisualProperty.ReleasePolicy);
+                releasePoli?.Get(out ret);
                 releasePoli?.Dispose();
 
                 return (ReleasePolicyType)ret;
@@ -1024,16 +949,24 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return (WrapModeType)GetValue(WrapModeUProperty);
+            }
+            set
+            {
+                SetValue(WrapModeUProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        private WrapModeType InternalWrapModeU
+        {
+            get
+            {
                 int ret = (int)WrapModeType.Default;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue warpModeU = imageMap?.Find(ImageVisualProperty.WrapModeU);
-                warpModeU?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
-                warpModeU?.Dispose();
+                PropertyValue wrapModeU = _imagePropertyMap?.Find(ImageVisualProperty.WrapModeU);
+                wrapModeU?.Get(out ret);
+                wrapModeU?.Dispose();
 
                 return (WrapModeType)ret;
             }
@@ -1059,15 +992,23 @@ namespace Tizen.NUI.BaseComponents
         {
             get
             {
+                return (WrapModeType)GetValue(WrapModeVProperty);
+            }
+            set
+            {
+                SetValue(WrapModeVProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+
+        private WrapModeType InternalWrapModeV
+        {
+            get
+            {
                 int ret = (int)WrapModeType.Default;
-                PropertyMap imageMap = new PropertyMap();
-                PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-                image?.Get(imageMap);
-                PropertyValue wrapModeV = imageMap?.Find(ImageVisualProperty.WrapModeV);
-                wrapModeV?.Get(out ret);
 
-                imageMap?.Dispose();
-                image?.Dispose();
+                PropertyValue wrapModeV = _imagePropertyMap?.Find(ImageVisualProperty.WrapModeV);
+                wrapModeV?.Get(out ret);
                 wrapModeV?.Dispose();
 
                 return (WrapModeType)ret;
@@ -1081,7 +1022,46 @@ namespace Tizen.NUI.BaseComponents
         }
 
         /// <summary>
-        /// Get attribues, it is abstract function and must be override.
+        /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
+        /// </summary>
+        /// <remarks>
+        /// This is false by default.
+        /// If this is set to be true, then the width or height value, which is not set by user explicitly, can be changed automatically
+        /// to preserve the aspect ratio of the image resource.
+        /// AdjustViewSize works only if ImageView is added to a View having Layout.
+        /// e.g. If the image resource size is (100, 100), then the ImageView requests size (100, 100) to its parent layout by default.
+        ///      If the ImageView's HeightSpecification is 50 and AdjustViewSize is true, then the ImageView requests size (50, 50) instead of (100, 50).
+        /// </remarks>
+        /// <since_tizen> 9 </since_tizen>
+        public bool AdjustViewSize
+        {
+            get
+            {
+                return (bool)GetValue(AdjustViewSizeProperty);
+            }
+            set
+            {
+                SetValue(AdjustViewSizeProperty, value);
+                NotifyPropertyChanged();
+            }
+        }
+        private bool adjustViewSize = false;
+
+        internal Selector<string> ResourceUrlSelector
+        {
+            get => GetSelector<string>(resourceUrlSelector, ImageView.ResourceUrlProperty);
+            set
+            {
+                resourceUrlSelector?.Reset(this);
+                if (value == null) return;
+
+                if (value.HasAll()) SetResourceUrl(value.All);
+                else resourceUrlSelector = new TriggerableSelector<string>(this, value, SetResourceUrl, true);
+            }
+        }
+
+        /// <summary>
+        /// Get attributes, it is abstract function and must be override.
         /// </summary>
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected override ViewStyle CreateViewStyle()
@@ -1114,7 +1094,53 @@ namespace Tizen.NUI.BaseComponents
         {
             base.ApplyCornerRadius();
 
-            UpdateImage(0, null);
+            if (backgroundExtraData == null) return;
+
+            // Apply corner radius to IMAGE.
+            var cornerRadiusValue = backgroundExtraData.CornerRadius == null ? new PropertyValue() : new PropertyValue(backgroundExtraData.CornerRadius);
+            var cornerRadiusPolicyValue = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy);
+
+            // Make current propertyMap
+            PropertyMap currentPropertyMap = new PropertyMap();
+            currentPropertyMap[Visual.Property.CornerRadius] = cornerRadiusValue;
+            currentPropertyMap[Visual.Property.CornerRadiusPolicy] = cornerRadiusPolicyValue;
+            var temp = new PropertyValue(currentPropertyMap);
+
+            // Update corner radius properties to image by ActionUpdateProperty
+            this.DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, temp);
+
+            temp.Dispose();
+            currentPropertyMap.Dispose();
+            cornerRadiusValue.Dispose();
+            cornerRadiusPolicyValue.Dispose();
+        }
+
+        internal override void ApplyBorderline()
+        {
+            base.ApplyBorderline();
+
+            if (backgroundExtraData == null) return;
+
+            // Apply borderline to IMAGE.
+            var borderlineWidthValue = new PropertyValue(backgroundExtraData.BorderlineWidth);
+            var borderlineColorValue = backgroundExtraData.BorderlineColor == null ? new PropertyValue(Color.Black) : new PropertyValue(backgroundExtraData.BorderlineColor);
+            var borderlineOffsetValue = new PropertyValue(backgroundExtraData.BorderlineOffset);
+
+            // Make current propertyMap
+            PropertyMap currentPropertyMap = new PropertyMap();
+            currentPropertyMap[Visual.Property.BorderlineWidth] = borderlineWidthValue;
+            currentPropertyMap[Visual.Property.BorderlineColor] = borderlineColorValue;
+            currentPropertyMap[Visual.Property.BorderlineOffset] = borderlineOffsetValue;
+            var temp = new PropertyValue(currentPropertyMap);
+
+            // Update borderline properties to image by ActionUpdateProperty
+            this.DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, temp);
+
+            temp.Dispose();
+            currentPropertyMap.Dispose();
+            borderlineWidthValue.Dispose();
+            borderlineColorValue.Dispose();
+            borderlineOffsetValue.Dispose();
         }
 
         internal ResourceLoadingStatusType GetResourceStatus()
@@ -1141,8 +1167,16 @@ namespace Tizen.NUI.BaseComponents
                 //You should release all of your own disposable objects here.
                 _border?.Dispose();
                 _border = null;
-                borderSelector.Reset(this);
-                resourceUrlSelector.Reset(this);
+                borderSelector?.Reset(this);
+                resourceUrlSelector?.Reset(this);
+                _imagePropertyUpdatedFlag = false;
+                if (_imagePropertyUpdateProcessAttachedFlag)
+                {
+                    ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
+                    _imagePropertyUpdateProcessAttachedFlag = false;
+                }
+                _imagePropertyMap?.Dispose();
+                _imagePropertyMap = null;
             }
 
             base.Dispose(type);
@@ -1170,73 +1204,157 @@ namespace Tizen.NUI.BaseComponents
             }
         }
 
-        private void UpdateImageMap(PropertyMap fromMap)
+        private void SetResourceUrl(string value)
         {
-            PropertyMap imageMap = new PropertyMap();
-
-            PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
-            image?.Get(imageMap);
-            imageMap?.Merge(fromMap);
-            PropertyValue setValue = new PropertyValue(imageMap);
-            SetProperty(ImageView.Property.IMAGE, setValue);
+            value = (value == null ? "" : value);
+            if (value.StartsWith("*Resource*"))
+            {
+                string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+                value = value.Replace("*Resource*", resource);
+            }
+            if(_resourceUrl != value)
+            {
+                _resourceUrl = value;
+                UpdateImage(ImageVisualProperty.URL, new PropertyValue(value));
+            }
+        }
 
-            imageMap?.Dispose();
-            image?.Dispose();
-            setValue?.Dispose();
+        private void SetBorder(Rectangle value)
+        {
+            if (value == null)
+            {
+                return;
+            }
+            if(_border != value)
+            {
+                _border = new Rectangle(value);
+                UpdateImage(NpatchImageVisualProperty.Border, new PropertyValue(_border));
+            }
         }
 
-        private void UpdateImage(int key, PropertyValue value)
+        /// <summary>
+        /// Lazy call to UpdateImage.
+        /// Collect Properties need to be update, and set properties that starts the Processing.
+        /// </summary>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected void UpdateImage(int key, PropertyValue value)
         {
-            PropertyMap imageMap = new PropertyMap();
+            // If we set ResourceUrl as empty, Unregist visual.
+            if (key == ImageVisualProperty.URL && string.IsNullOrEmpty(_resourceUrl))
+            {
+                // If previous resourceUrl was already empty, we don't need to do anything. just ignore.
+                // Unregist and dettach Process only if previous resourceUrl was not empty
+                string currentResourceUrl = "";
+                PropertyValue currentResourceUrlValue = _imagePropertyMap?.Find(ImageVisualProperty.URL);
+                if((currentResourceUrlValue?.Get(out currentResourceUrl) ?? false) && !string.IsNullOrEmpty(currentResourceUrl))
+                {
+                    PropertyValue emptyValue = new PropertyValue();
+
+                    // Remove current registed Image.
+                    SetProperty(ImageView.Property.IMAGE, emptyValue);
+
+                    // Image visual is not exist anymore. We should ignore lazy UpdateImage
+                    _imagePropertyUpdatedFlag = false;
+                    if(_imagePropertyUpdateProcessAttachedFlag)
+                    {
+                        ProcessorController.Instance.ProcessorOnceEvent -= UpdateImage;
+                        _imagePropertyUpdateProcessAttachedFlag = false;
+                    }
+                    // Update resourceUrl as null
+                    _imagePropertyMap[ImageVisualProperty.URL] = emptyValue;
 
-            if (_alphaMaskUrl != null)
+                    emptyValue?.Dispose();
+                }
+                return;
+            }
+
+            // Update image property map value as inputed value.
+            if (key != 0)
             {
-                PropertyValue alphaMaskUrl = new PropertyValue(_alphaMaskUrl);
-                imageMap?.Insert(ImageVisualProperty.AlphaMaskURL, alphaMaskUrl);
-                alphaMaskUrl?.Dispose();
+                if (_imagePropertyMap == null)
+                {
+                    _imagePropertyMap = new PropertyMap();
+                }
+                _imagePropertyUpdatedFlag = true;
+                _imagePropertyMap[key] = value;
+
+                // Lazy update only if _resourceUrl is not empty and ProcessAttachedFlag is false.
+                if (!string.IsNullOrEmpty(_resourceUrl) && !_imagePropertyUpdateProcessAttachedFlag)
+                {
+                    _imagePropertyUpdateProcessAttachedFlag = true;
+                    ProcessorController.Instance.ProcessorOnceEvent += UpdateImage;
+                    // Call process hardly.
+                    ProcessorController.Instance.Awake();
+                }
             }
+        }
+
+        /// <summary>
+        /// Callback function to Lazy UpdateImage.
+        /// </summary>
+        private void UpdateImage(object source, EventArgs e)
+        {
+            UpdateImage();
+            _imagePropertyUpdateProcessAttachedFlag = false;
+        }
 
-            if (string.IsNullOrEmpty(_resourceUrl))
+        /// <summary>
+        /// Update image-relative properties synchronously.
+        /// After call this API, All image properties updated.
+        /// </summary>
+        /// <remarks>
+        /// Current version ImageView property update asynchronously.
+        /// If you want to guarantee that ImageView property setuped,
+        /// Please call this ImageView.UpdateImage() API.
+        /// </remarks>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        protected void UpdateImage()
+        {
+            if(!_imagePropertyUpdatedFlag) return;
+
+            _imagePropertyUpdatedFlag = false;
+
+            if(_imagePropertyMap == null)
             {
-                PropertyValue resourceUrl = new PropertyValue(_resourceUrl);
-                imageMap?.Insert(ImageVisualProperty.URL, resourceUrl);
-                PropertyValue setValue = new PropertyValue(imageMap);
-                SetProperty(ImageView.Property.IMAGE, setValue);
-                resourceUrl?.Dispose();
-                setValue?.Dispose();
-                return;
+                _imagePropertyMap = new PropertyMap();
             }
 
             if (_border == null)
             {
                 PropertyValue image = new PropertyValue((int)Visual.Type.Image);
-                imageMap?.Insert(Visual.Property.Type, image);
+                _imagePropertyMap[Visual.Property.Type] = image;
                 image?.Dispose();
             }
             else
             {
                 PropertyValue nPatch = new PropertyValue((int)Visual.Type.NPatch);
-                imageMap?.Insert(Visual.Property.Type, nPatch);
+                _imagePropertyMap[Visual.Property.Type] = nPatch;
                 nPatch?.Dispose();
                 PropertyValue border = new PropertyValue(_border);
-                imageMap?.Insert(NpatchImageVisualProperty.Border, border);
+                _imagePropertyMap[NpatchImageVisualProperty.Border] = border;
                 border?.Dispose();
             }
 
-            PropertyValue synchronosLoading = new PropertyValue(_synchronosLoading);
-            imageMap?.Insert(NpatchImageVisualProperty.SynchronousLoading, synchronosLoading);
-            synchronosLoading?.Dispose();
-
-            if (backgroundExtraData != null && backgroundExtraData.CornerRadius > 0)
+            if (backgroundExtraData != null && backgroundExtraData.CornerRadius != null)
             {
-                PropertyValue cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius);
-                imageMap?.Insert(Visual.Property.CornerRadius, cornerRadius);
-                cornerRadius?.Dispose();
+                using (var cornerRadius = new PropertyValue(backgroundExtraData.CornerRadius))
+                using (var cornerRadiusPolicy = new PropertyValue((int)backgroundExtraData.CornerRadiusPolicy))
+                {
+                    _imagePropertyMap[Visual.Property.CornerRadius] = cornerRadius;
+                    _imagePropertyMap[Visual.Property.CornerRadiusPolicy] = new PropertyValue((int)(backgroundExtraData.CornerRadiusPolicy));
+                }
             }
 
-            if (value != null)
+            if (backgroundExtraData != null && backgroundExtraData.BorderlineWidth > 0.0f)
             {
-                imageMap?.Insert(key, value);
+                using (var borderlineWidth = new PropertyValue(backgroundExtraData.BorderlineWidth))
+                using (var borderlineColor = new PropertyValue(backgroundExtraData.BorderlineColor))
+                using (var borderlineOffset = new PropertyValue(backgroundExtraData.BorderlineOffset))
+                {
+                    _imagePropertyMap[Visual.Property.BorderlineWidth] = borderlineWidth;
+                    _imagePropertyMap[Visual.Property.BorderlineColor] = borderlineColor;
+                    _imagePropertyMap[Visual.Property.BorderlineOffset] = borderlineOffset;
+                }
             }
 
             // Do Fitting Buffer when desired dimension is set
@@ -1244,42 +1362,73 @@ namespace Tizen.NUI.BaseComponents
             {
                 if (_resourceUrl != null)
                 {
-                  Size2D originalImageSize = ImageLoading.GetOriginalImageSize(_resourceUrl);
-                  Size2D imageSize = originalImageSize;
-                  originalImageSize?.Dispose();
-
-                  int adjustedDesiredWidth, adjustedDesiredHeight;
-                  float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
-                  float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
-                  if( aspectOfImageSize > aspectOfDesiredSize)
-                  {
-                      adjustedDesiredWidth = _desired_width;
-                      adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
-                  }
-                  else
-                  {
-                      adjustedDesiredWidth = imageSize.Width * _desired_height/ imageSize.Height;
-                      adjustedDesiredHeight = _desired_height;
-                  }
-
-                  PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
-                  imageMap?.Insert(ImageVisualProperty.DesiredWidth, returnWidth);
-                  returnWidth?.Dispose();
-                  PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
-                  imageMap?.Insert(ImageVisualProperty.DesiredHeight, returnHeight);
-                  returnHeight?.Dispose();
-                  PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
-                  imageMap?.Insert(ImageVisualProperty.FittingMode, scaleToFit);
-                  scaleToFit?.Dispose();
+                    Size2D imageSize = ImageLoader.GetOriginalImageSize(_resourceUrl, true);
+                    if( imageSize.Height > 0 && imageSize.Width > 0 && _desired_width > 0  && _desired_height > 0 )
+                    {
+                        int adjustedDesiredWidth, adjustedDesiredHeight;
+                        float aspectOfDesiredSize = (float)_desired_height / (float)_desired_width;
+                        float aspectOfImageSize = (float)imageSize.Height / (float)imageSize.Width;
+                        if (aspectOfImageSize > aspectOfDesiredSize)
+                        {
+                            adjustedDesiredWidth = _desired_width;
+                            adjustedDesiredHeight = imageSize.Height * _desired_width / imageSize.Width;
+                        }
+                        else
+                        {
+                            adjustedDesiredWidth = imageSize.Width * _desired_height / imageSize.Height;
+                            adjustedDesiredHeight = _desired_height;
+                        }
+
+                        PropertyValue returnWidth = new PropertyValue(adjustedDesiredWidth);
+                        _imagePropertyMap[ImageVisualProperty.DesiredWidth] = returnWidth;
+                        returnWidth?.Dispose();
+                        PropertyValue returnHeight = new PropertyValue(adjustedDesiredHeight);
+                        _imagePropertyMap[ImageVisualProperty.DesiredHeight] = returnHeight;
+                        returnHeight?.Dispose();
+                        PropertyValue scaleToFit = new PropertyValue((int)FittingModeType.ScaleToFill);
+                        _imagePropertyMap[ImageVisualProperty.FittingMode] = scaleToFit;
+                        scaleToFit?.Dispose();
+                    }
+                    else
+                    {
+                        Tizen.Log.Fatal("NUI", "[ERROR] Can't use DesiredSize when ImageLoading is failed.");
+                    }
+                    imageSize?.Dispose();
                 }
             }
 
-            UpdateImageMap(imageMap);
+            UpdateImageMap();
+        }
+        private void UpdateImageMap()
+        {
+            PropertyMap imageMap = new PropertyMap();
+
+            PropertyValue image = Tizen.NUI.Object.GetProperty(SwigCPtr, ImageView.Property.IMAGE);
+            image?.Get(imageMap);
+            imageMap.Merge(_imagePropertyMap);
+            PropertyValue setValue = new PropertyValue(imageMap);
+            SetProperty(ImageView.Property.IMAGE, setValue);
+
+            // Sync local PropertyMap
+            // TODO: Do we need to use GetProperty(SwigCPtr, ImageView.Property.IMAGE); here?
+            _imagePropertyMap.Dispose();
+            _imagePropertyMap = new PropertyMap(imageMap);
 
             imageMap?.Dispose();
-            imageMap = null;
+            image?.Dispose();
+            setValue?.Dispose();
         }
 
+        /// <summary>
+        /// GetNaturalSize() should be guaranteed that ResourceUrl property setuped.
+        /// So before get base.GetNaturalSize(), we should synchronous image properties
+        /// </summary>
+        internal override Vector3 GetNaturalSize()
+        {
+            // Sync as current properties
+            UpdateImage();
+            return base.GetNaturalSize();
+        }
 
         private void OnResourceLoaded(IntPtr view)
         {
@@ -1338,10 +1487,6 @@ namespace Tizen.NUI.BaseComponents
             internal static readonly int IMAGE = Interop.ImageView.ImageGet();
             internal static readonly int PreMultipliedAlpha = Interop.ImageView.PreMultipliedAlphaGet();
             internal static readonly int PixelArea = Interop.ImageView.PixelAreaGet();
-            internal static readonly int ActionReload = Interop.ImageView.ImageVisualActionReloadGet();
-            internal static readonly int ActionPlay = Interop.ImageView.ImageVisualActionPlayGet();
-            internal static readonly int ActionPause = Interop.ImageView.ImageVisualActionPauseGet();
-            internal static readonly int ActionStop = Interop.ImageView.ImageVisualActionStopGet();
         }
 
         private enum ImageType
@@ -1370,5 +1515,100 @@ namespace Tizen.NUI.BaseComponents
         {
             PixelArea = new RelativeVector4(x, y, z, w);
         }
+
+        private class ImageLayout : LayoutItem
+        {
+            /// <summary>
+            /// Gets or sets the mode to adjust view size to preserve the aspect ratio of the image resource.
+            /// If this is set to be true, then the width or height, which is not set by user explicitly, can be adjusted to preserve the aspect ratio of the image resource.
+            /// </summary>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            public bool AdjustViewSize
+            {
+                get
+                {
+                    return (Owner as ImageView)?.AdjustViewSize ?? false;
+                }
+                set
+                {
+                    if (Owner is ImageView imageView)
+                    {
+                        imageView.AdjustViewSize = value;
+                    }
+                }
+            }
+
+            /// <inheritdoc/>
+            [EditorBrowsable(EditorBrowsableState.Never)]
+            protected override void OnMeasure(MeasureSpecification widthMeasureSpec, MeasureSpecification heightMeasureSpec)
+            {
+                // To not change the view size by DALi
+                Owner.WidthResizePolicy = ResizePolicyType.Fixed;
+                Owner.HeightResizePolicy = ResizePolicyType.Fixed;
+
+                float specWidth = widthMeasureSpec.Size.AsDecimal();
+                float specHeight = heightMeasureSpec.Size.AsDecimal();
+                float naturalWidth = Owner.NaturalSize.Width;
+                float naturalHeight = Owner.NaturalSize.Height;
+                float minWidth = Owner.MinimumSize.Width;
+                float maxWidth = Owner.MaximumSize.Width;
+                float minHeight = Owner.MinimumSize.Height;
+                float maxHeight = Owner.MaximumSize.Height;
+                float aspectRatio = (naturalWidth > 0) ? (naturalHeight / naturalWidth) : 0;
+
+                // Assume that the new width and height are given from the view's suggested size by default.
+                float newWidth = Math.Min(Math.Max(naturalWidth, minWidth), (maxWidth < 0 ? Int32.MaxValue : maxWidth));
+                float newHeight = Math.Min(Math.Max(naturalHeight, minHeight), (maxHeight < 0 ? Int32.MaxValue : maxHeight));
+
+                // The width and height measure specs are going to be used to set measured size.
+                // Mark that the measure specs are changed by default to update measure specs later.
+                bool widthSpecChanged = true;
+                bool heightSpecChanged = true;
+
+                if (widthMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
+                {
+                    newWidth = specWidth;
+                    widthSpecChanged = false;
+
+                    if (heightMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
+                    {
+                        if ((AdjustViewSize) && (aspectRatio > 0))
+                        {
+                            newHeight = newWidth * aspectRatio;
+                        }
+                    }
+                }
+
+                if (heightMeasureSpec.Mode == MeasureSpecification.ModeType.Exactly)
+                {
+                    newHeight = specHeight;
+                    heightSpecChanged = false;
+
+                    if (widthMeasureSpec.Mode != MeasureSpecification.ModeType.Exactly)
+                    {
+                        if ((AdjustViewSize) && (aspectRatio > 0))
+                        {
+                            newWidth = newHeight / aspectRatio;
+                        }
+                    }
+                }
+
+                if (widthSpecChanged)
+                {
+                    widthMeasureSpec = new MeasureSpecification(new LayoutLength(newWidth), MeasureSpecification.ModeType.Exactly);
+                }
+
+                if (heightSpecChanged)
+                {
+                    heightMeasureSpec = new MeasureSpecification(new LayoutLength(newHeight), MeasureSpecification.ModeType.Exactly);
+                }
+
+                MeasuredSize.StateType childWidthState = MeasuredSize.StateType.MeasuredSizeOK;
+                MeasuredSize.StateType childHeightState = MeasuredSize.StateType.MeasuredSizeOK;
+
+                SetMeasuredDimensions(ResolveSizeAndState(new LayoutLength(newWidth), widthMeasureSpec, childWidthState),
+                                      ResolveSizeAndState(new LayoutLength(newHeight), heightMeasureSpec, childHeightState));
+            }
+        }
     }
 }