شروع کار با Angular Material ۲
<md-tab-group> <md-tab label="Tab 1">Content 1</md-tab> <md-tab label="Tab 2">Content 2</md-tab> </md-tab-group>
برنامهی آنلاینی جهت تولید یک theme سفارشی جدید برای ویژوال استودیو ایجاد شده است که در آدرس زیر قابل استفاده است:
ابتدا تنظیمات رنگ خود را انتخاب کنید، سپس بر روی دکمه refresh کلیک نمائید تا نمونهای از نتیجهی کار را بتوان مشاهده کرد و سپس بر روی دکمه create کلیک کنید.
و برای استفاده از فایل تولید شده از طریق منوی tools گزینهی Import and Export Settings اقدام کنید.
ایجاد چارت سازمانی تحت وب #2
OpenCVSharp #11
using (var src = new Mat(@"test.jpg", LoadMode.Color)) { image1.Source = KMeans(src, 2).ToWriteableBitmap(); image2.Source = Binary(src).ToWriteableBitmap(); }
private static Mat Binary(Mat src) { // Convert the image to Gray src = src.CvtColor(ColorConversion.RgbToGray); // Convert the Gray to Binary with auto threshold Cv2.Threshold(src, src, 0, 255, ThresholdType.Binary | ThresholdType.Otsu); // Convert the Gray to Binary with manual threshold //Cv2.Threshold(src, src, 127, 255, ThresholdType.Binary); return src; } private static Mat KMeans(Mat src, int k) { var columnVector = src.Reshape(cn: 3, rows: src.Rows * src.Cols); var samples = new Mat(); columnVector.ConvertTo(samples, MatType.CV_32FC3); var bestLabels = new Mat(); var centers = new Mat(); Cv2.Kmeans( data: samples, k: k, bestLabels: bestLabels, criteria: new TermCriteria(type: CriteriaType.Epsilon | CriteriaType.Iteration, maxCount: 10, epsilon: 1.0), attempts: 3, flags: KMeansFlag.PpCenters, centers: centers); var dst = new Mat(src.Rows, src.Cols, src.Type()); for (var size = 0; size < src.Cols * src.Rows; size++) { var clusterIndex = bestLabels.At<int>(0, size); var newPixel = new Vec3b { Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R }; dst.Set(size / src.Cols, size % src.Cols, newPixel); } return dst; }
نتایج :
import { Component, Input, OnInit } from '@angular/core'; import { AbstractControl } from '@angular/forms'; @Component({ selector: 'validation-message', template: ` <ng-container *ngIf="control.invalid && control.touched"> {{ message }} </ng-container> ` }) export class ValidationMessageComponent implements OnInit { @Input() control: AbstractControl; @Input() fieldDisplayName: string; @Input() rules: { [key: string]: string }; get message(): string { return this.control.hasError('required') ? `${this.fieldDisplayName} را وارد نمائید.` : this.control.hasError('pattern') ? `${this.fieldDisplayName} را به شکل صحیح وارد نمائید.` : this.control.hasError('email') ? `${this.fieldDisplayName} را به شکل صحیح وارد نمائید.` : this.control.hasError('minlength') ? `${this.fieldDisplayName} باید بیشتر از ${ this.control.errors.minlength.requiredLength } کاراکتر باشد.` : this.control.hasError('maxlength') ? `${this.fieldDisplayName} باید کمتر از ${ this.control.errors.maxlength.requiredLength } کاراکتر باشد.` : this.control.hasError('min') ? `${this.fieldDisplayName} باید بیشتر از ${ this.control.errors.min.requiredLength } باشد.` : this.control.hasError('max') ? `${this.fieldDisplayName} باید کمتر از ${ this.control.errors.max.requiredLength } باشد.` : this.hasRule() ? this.findRule() : this.control.hasError('model') ? `${this.control.errors.model.messages[0]}` : ''; } constructor() {} private hasRule() { return ( this.rules && Object.keys(this.control.errors).some(ruleKey => this.rules[ruleKey] ? true : false ) ); } private findRule(): string { let message = ''; Object.keys(this.control.errors).forEach(ruleKey => { if (this.rules[ruleKey]) { message += `${this.rules[ruleKey]} `; } }); return message; } ngOnInit(): void {} }
<mat-error *ngIf="form.controls['userName'].invalid && form.controls['userName'].touched" class="mat-text-warn"> <validation-message [control]="form.controls['userName']" fieldDisplayName="نام کاربری" [rules]="{rule1:'پیغام متناظر با rule1'}"> </validation-message> </mat-error>
this.form = this.formBuilder.group({ userName: [ '', [Validators.required, UserNameValidators.rule1)] ], password: ['', Validators.required], rememberMe: [false] }); export class UserNameValidators{ static rule1(control: AbstractControl) { if (control.value.indexOf(' ') >= 0) { return { rule1: true }; } return null; } }
در قسمت قبلی درباره ایجاد نمودار سازمانی تحت وب صحبت کردیم .حال اگر بخواهیم آن را با رنگهای مختلف ایجاد کنیم مانند شکل ذیل :
بدین صورت باید عمل کنیم:
نمودار در داخل canvas رسم شده است. برای اینکه پس زمینه (background) و حاشیههای آن (borders) را رنگ آمیزی کنیم، باید تابع رنگ آمیزی را قبل از تابع رسم نمودار صدا بزنیم. میتوانید از کدهای ذیل استفاده نمائید:
// ایجاد یک پس زمینه رنگی: var c = document.getElementById("c_canvas"); var cxt = c.getContext("2d"); var gradient = cxt.createLinearGradient(0, 0, 800, 320) gradient.addColorStop(0, 'Red'); gradient.addColorStop(.5, 'Yellow'); gradient.addColorStop(1, 'Green'); cxt.fillStyle = gradient; cxt.fillRect(0, 0, 800, 320); cxt.save(); // این سه خط را فعال کرده تا انتقال نمودار چارت سازمانی را مشاهده نمائید. //cxt.scale(-1.1, 1.1); //cxt.translate(-700,-50); //cxt.rotate(0.2); var o = new orgChart(); o.addNode(1, '', '', 'Root node'); o.addNode(2, 1, 'u', 'u-node 1'); o.addNode(3, 1, 'u', 'u-node 2'); o.addNode(4, 1, 'u', 'u-node 3'); o.addNode(5, 1, 'l', 'l-node 1'); o.addNode(6, 1, 'l', 'l-node 2'); o.addNode(7, 1, 'r', 'r-node 1'); o.addNode(8, 1, 'r', 'r-node 2'); o.addNode(9, 1, 'r', 'r-node 3'); o.addNode('', '', '', 'Root 2'); o.addNode('', 'Root 2', 'r', 'using'); o.addNode('', 'Root 2', 'r', 'text as id'); o.drawChart('c_canvas', 'center'); cxt.restore();
نکته : اگر بخواهید رنگ پس زمینه canvas را کامل پر کند (Fill) باید رسم نمودار را دوبار انجام دهید، در ابتدا تعریف یک canvas با امکان پرشونده در صفحه ، و بعد رسم پس زمینه و بعد رسم دوباره canvas .
رنگها
شاخهها میتوانند رنگهای متفاوتی داشته باشند. امکان تعریف رنگ شاخهها بهمراه صدا زدن تابع addNode وجود دارد. اگر رنگی تعریف نشود ، از رنگ پیشفرض استفاده خواهد شد. رنگهای کنونی را با صدا زدن تابع setColor میتوان عوض کرد و تا زمان صدا زدن تابع setColor بعدی از آنها استفاده خواهد شد. همه خطهایی که شاخهها را به هم متصل میکنند فقط یک رنگ مشابه میتوانند داشته باشند.
پارامترهای تابع setColor :
- رنگ خطوط حاشیه ( اختیاری )
- رنگ پرکننده شاخه ( اختیاری )
- رنگ نوشته / عنوان شاخه ( اختیاری )
- رنگ خطوط متصل کننده ( اختیاری ، عمومی )
یک پارامتر خالی رنگ ، تنظیمات کنونی را تغییر نخواهد داد. کد زیر را ویرایش نموده و دوباره صفحه خود را بازخوانی نمائید.
var o = new orgChart(); o.setColor('#99CC99', '#CCFFCC', '#000000', '#FF0000'); o.addNode(0, '', '', 'Root node'); o.setColor('#CCCC66', '#FFFF99'); o.addNode(11, 0, 'u', 'u-node 1'); o.setColor('#000000', '#FFFF99'); o.addNode(12, 0, 'u', 'black border'); o.addNode(13, 0, 'u', 'bold black border', 1); o.setColor('#CC4950', '#FF7C80'); o.addNode(21, 0, 'l', 'l-node 1'); o.addNode(22, 0, 'l', 'l-node 2', 0, 'BLACK', 'RED', 'BLUE'); o.addNode(23, 0, 'l', 'l-node 3'); o.setColor('#CC9966', '#FFCC99'); o.addNode(31, 0, 'r', 'r-node 1'); o.drawChart('c_colors', 'center');
استفاده از CSS علاوه بر جذابیت و قابلیتهای مفید آن، پیچیدگی هایی دارد و کدهای شما معمولا طولانی میشود و هرچه کدها طولانیتر شوند، مدیریت آن نیز سختتر میگردد. اما با استفاده از SASS ، قابلیت هایی به Css اضافه میشود که قبلا وجود نداشت، از جمله استفاده از varible ها، نوشتن کدهای تو در تو ( nesting ) و … . با استفاده از SASS کدهای CSS کوتاهتر شده و در نتیجه سریعتر اجرا شوند. SASS با CSS3 سازگار است. همچنین امکان مشاهده فایلهای آن (با پسوند .scss ) توسط افزونه Firesass For Firebug وجود دارد.
دو syntax برای SASS وجود دارد: یکی SCSS (Sassy CSS) که شکل توسعه یافته CSS3 می باشدو دیگری که قدیمیتر است، Indented syntax میباشد که در آن به جای استفاده از براکت، از تورفتگی خطهای کد استفاده میشود و همچنین از به جای استفاده از سمی کولن ، باید به خط جدید بروید.
قابلیتهای موجود در SASS :
1- Variables
متغیرها امکان ایجاد تغییرات در کدهای CSS را بسیار راحتتر میسازند. به عنوان مثال یک متغیر برای یک کد رنگ دلخواه تعریف میکنید، از این به بعد به جای استفاده از کد رنگ در کدهای CSS ، از متغیر تعریف شده برای آن بهره میگیرید، به این ترتیب ، چنانچه در آینده نیاز به تغییر این کد رنگ داشته باشید، تنها با تغییر آن در متغیر ، در کل فایل CSS تغییر ایجاد خواهد شد . برای تعریف متغیر ، در ابتدای اسم دلخواه خود از علامت $ استفاده کنید:
$myColor: #ff0000; body { color: $myColor; } .box{ Border-color:$myColor; }
Nesting -2 یا selector های تو در تو:
می توانید selector ها را مانند کدهای html به صورت hirearchy تعریف کنید:
nav { ul { list-style: none; } li { display: inline-block; } a { text-decoration: none; } }
nav ul { list-style: none; } nav li { display: inline-block; } nav a { text-decoration: none; }
3- Partials :
می توانید قطعاتی از کدهای CSS را به صورت Partial SASS تعریف کنید و سپس آن را در فایلهای SASS دیگر استفاده نمایید.همانند Partialview در MVC ، هنگام نام گذاری آن از _ در ابتدای نام استفاده نمایید. فایل partial SASS دارای پسوند .SCSS می باشد : " "_myPartial.scss
برای استفاده از _myPartial.scss در فایل sass دیگر ، از دایرکتیو @import استفاده کنید:
@import "myPartial"
@import "mypartial1","myPartial2"
/*_myPartial1.scss codes…*/ html,body,ul,ol { margin: 0; padding: 0; } /*_myPartial2.scss codes…*/ @import "myPartial1" body, { background-color: #efefef; }
html, body, ul, ol { margin: 0; padding: 0; } body { background-color: #efefef; }
4- Mixins :
از آنجایی که استفاده و نوشتن بعضی property های CSS سخت میباشد، میتوانید از روش mixin استفاده کرده و قطعه کدهایی را ایجاد کنید که بتوانید در کدهایتان از آنها بارها و بارها استفاده کنید. به عنوان مثال قطع کدی برای border-radius ایجاد کنید ، (همانطور که میدانید border-radius برای مرورگرهای مختلف ، حالتهای مختلفی تعریف میشود.). برای ایجاد mixin ، در ابتدای قطع کد از @mixin استفاده نمایید و برای استفاده ازآن ، از @include استفاده نمایید:
@mixin cssProperty $yourCustomName{ … Your css properties… }
نمونه کد:
ایجاد mixin: @mixin border-radius($radius) { -webkit-border-radius: $radius; -moz-border-radius: $radius; -ms-border-radius: $radius; -o-border-radius: $radius; border-radius: $radius; } استفاده از mixin: .box { @include border-radius(10px); }
Extend/Inheritance -5 :
@XETEND به شما این امکان را میدهد تا بخشی از Property های یک selector را برای استفاده در selector های دیگر به اشتراک بگذارید:
.message { border: 1px solid #ccc; padding: 10px; color: #333; } .success { @extend .message; border-color: green; }
کدها بعد از تولید شدن به صورت زیر دیده میشوند:
.message, .success { border: 1px solid #cccccc; padding: 10px; color: #333; } .success { border-color: green; }
6- Operators :
می توانید از عملگرهای ضرب و تقسیم و جمع و تفریق در کدهای CSS خود استفاده نمایید:
article[role="main"] { float: left; width: 600px / 960px * 100%; }
نصب SASS :
حال که با SASS آشنا شدید ، انگیزه کافی برای دانستن روش نصب و استفاده آن خواهید داشت. برای استفاده از SASS می توانید از نرم افزارهایی که برای ویندوز ، مک و لینوکس وجود دارند، استفاده کنید از جمله این نرم افزارها :
CodeKit , Compass.app , Hammer , Koala , LiveReload , Mixture , Prepros , Prepros Pro , Scout
روش دیگر استفاده از command line میباشد:
چنانچه سیستم عامل شما ویندوز میباشد، برای استفاده از sass ابتدا باید rubby را نصب نمایید. سپس در Cmd خط زیر را اجرا کنید:
gem install sass
چنانچه به خطایی برخوردید، ابتدا gem توسط sudo را نصب کنید:
sudo gem install sass
سپس توسط خط زیر چک کنید که SASS نصب شده است یا خیر:
sass -v
Sass 3.2.12 (Media Mark)
برای کسب اطلاعات بیشتر و روش نصب در سایر سیستم عاملها به این لینک مراجعه نمایید.
SassScript :
فایل SASS اسکریپتی برای اجرای یک سری از فانکشنها دارد، از جمله :
- rgb($red, $green, $blue) /* برای ایجاد کد رنگ rgb */
برای مشاهده لیست کامل این فانکشنها به این لینک مراجعه کنید.
منبع
خلاصه اشتراکهای روز یک شنبه 15 آبان 1390
OpenCVSharp #10
هیستوگرام یک تصویر، توزیع میزان روشنایی آن تصویر را نمایش میدهد و در آن تعداد نقاط قسمتهای روشن تصویر، ترسیم میشوند. محاسبهی هیستوگرام تصاویر در حین دیباگ الگوریتمهای پردازش تصویر، کاربرد زیادی دارند.
OpenCV به همراه متد توکاری است به نام cv::calcHist که قادر است هیستوگرام تعدادی آرایه را محاسبه کند و در C++ API آن قرار دارد. البته هدف اصلی این متد، انجام محاسبات مرتبط است و در اینجا قصد داریم این محاسبات را نمایش دهیم.
تغییر میزان روشنایی و وضوح تصاویر در OpenCV
همانطور که عنوان شد، کار هیستوگرام تصاویر، نمایش توزیع میزان روشنایی نقاط و اجزای آنها است. بنابراین میتوان جهت مشاهدهی تغییر هیستوگرام محاسبه شده با تغییر میزان روشنایی و وضوح تصویر، از متد ذیل کمک گرفت:
private static void updateBrightnessContrast(Mat src, Mat modifiedSrc, int brightness, int contrast) { brightness = brightness - 100; contrast = contrast - 100; double alpha, beta; if (contrast > 0) { double delta = 127f * contrast / 100f; alpha = 255f / (255f - delta * 2); beta = alpha * (brightness - delta); } else { double delta = -128f * contrast / 100; alpha = (256f - delta * 2) / 255f; beta = alpha * brightness + delta; } src.ConvertTo(modifiedSrc, MatType.CV_8UC3, alpha, beta); }
پس از اینکه متد تغییر وضوح تصویر اصلی را تهیه کردیم، میتوان به پنجرهی نمایش تصویر اصلی، دو tracker جهت دریافت brightness و contrast اضافه کرد و به این ترتیب امکان نمایش پویای تغییرات را مهیا نمود:
using (var src = new Mat(@"..\..\Images\Penguin.Png", LoadMode.AnyDepth | LoadMode.AnyColor)) { using (var sourceWindow = new Window("Source", image: src, flags: WindowMode.AutoSize | WindowMode.FreeRatio)) { using (var histogramWindow = new Window("Histogram", flags: WindowMode.AutoSize | WindowMode.FreeRatio)) { var brightness = 100; var contrast = 100; var brightnessTrackbar = sourceWindow.CreateTrackbar( name: "Brightness", value: brightness, max: 200, callback: pos => { brightness = pos; updateImageCalculateHistogram(sourceWindow, histogramWindow, src, brightness, contrast); }); var contrastTrackbar = sourceWindow.CreateTrackbar( name: "Contrast", value: contrast, max: 200, callback: pos => { contrast = pos; updateImageCalculateHistogram(sourceWindow, histogramWindow, src, brightness, contrast); }); brightnessTrackbar.Callback.DynamicInvoke(brightness); contrastTrackbar.Callback.DynamicInvoke(contrast); Cv2.WaitKey(); } } }
پنجرهی دومی نیز به نام هیستوگرام در اینجا تعریف شدهاست. در این پنجره قصد داریم هیستوگرام تغییرات پویای تصویر اصلی را نمایش دهیم.
روش محاسبهی هیستوگرام تصاویر و نمایش آنها در OpenCVSharp
کدهای کامل محاسبهی هیستوگرام تصویر اصلی تغییر یافته (modifiedSrc) و سپس نمایش آنرا در پنجرهی histogramWindow، در ادامه ملاحظه میکنید:
private static void calculateHistogram1(Window histogramWindow, Mat src, Mat modifiedSrc) { const int histogramSize = 64; int[] dimensions = { histogramSize }; // Histogram size for each dimension Rangef[] ranges = { new Rangef(0, histogramSize) }; // min/max using (var histogram = new Mat()) { Cv2.CalcHist( images: new[] { modifiedSrc }, channels: new[] { 0 }, mask: null, hist: histogram, dims: 1, histSize: dimensions, ranges: ranges); using (var histogramImage = (Mat)(Mat.Ones(rows: src.Rows, cols: src.Cols, type: MatType.CV_8U) * 255)) { // Scales and draws histogram Cv2.Normalize(histogram, histogram, 0, histogramImage.Rows, NormType.MinMax); var binW = Cv.Round((double)histogramImage.Cols / histogramSize); var color = Scalar.All(100); for (var i = 0; i < histogramSize; i++) { Cv2.Rectangle(histogramImage, new Point(i * binW, histogramImage.Rows), new Point((i + 1) * binW, histogramImage.Rows - Cv.Round(histogram.Get<float>(i))), color, -1); } histogramWindow.Image = histogramImage; } } }
پس از محاسبهی هیستوگرام، یک تصویر خالی پر شدهی با عدد یک را توسط متد Mat.Ones ایجاد میکنیم. این تصویر به عنوان منبع تصویر هیستوگرام نمایش داده شده، مورد استفاده قرار میگیرد. سپس نیاز است اطلاعات محاسبه شده، در مقیاسی قرار گیرند که قابل نمایش باشد. به همین جهت با استفاده از متد Normalize، آنها را در مقیاس و بازهی ارتفاع تصویر، تغییر اندازه خواهیم داد. سپس به کمک متد مستطیل، خروجی آرایه هیستوگرام را در صفحه، با رنگ خاکستری مشخص شده توسط متد Scalar.All ترسیم خواهیم کرد.
همانطور که در این تصویر ملاحظه میکنید، با کدرتر شدن تصویر اصلی، هیستوگرام آن، توزیع روشنایی کمتری را نمایش میدهد.
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.