Case study: Image resize in a Browser

If you have ever come across the task of image resizing in a browser, you probably know that it is very simple. In every modern browser there is a special element <canvas>. You can put the image by defining the sizes. Five lines of code – and you got the image you wanted:

function resize(img, w, h) {
  var canvas = document.createElement('canvas');
  canvas.width = w;
  canvas.height = h;
  canvas.getContext('2d').drawImage(img, 0, 0, w, h);
  return canvas;
}

Afterwards, with the help of the canvas you can save the image as JPEG and send it to a server. What is the trick here? It all comes to the image quality. If you place such canvas and regular <img> that contains the same picture in it (source, 4 Mb), you will see the difference clearly.

image resize browser

For some reason all modern browsers (desktop or mobile) use a cheap method of affine transformation for drawing on canvas. Let’s recall the essence of the method. To calculate the position of every point of the final image, four points of the original image are taken. This means that reducing the image size in more than two times causes holes in the original image – pixels that are not taken into account in the final image. It is because of these forgotten pixels that the image quality suffers.

Of course, such picture should not be shown to respectable people. It does not come as a big surprise that the issue of resizing quality with the help of canvas is popular in stackoverflow. The most common advice is to shrink the picture in several steps. Indeed, if a too strong image reduction does not take into consideration all of the pixels, why not change the image gradually? Over and over again, until we get the desired size. Here is the example.

Undoubtedly, this method produces a far better result, since all the points of the original image are recognized in the final image. Another question is how exactly they recognized are. It depends on the step size, original and final image sizes. For example, if we choose a step size with the value 2, the reduction will be equivalent to supersampling. The last step is determined by chance. Every once in awhile, if you’re very lucky, the last step may also be equal to two. But if you are unlucky, you might be obliged to reduce the image by a pixel at the last step and as a result get a blurred image. Compare the difference by a single pixel on the below pictures (Source, 4 Mb):

image resize browser

Maybe we should take a completely different approach? We have a canvas from which one can get pixels and there is a super fast JavaScript that can quickly do the resizing. This means that we can implement any resizing method not relying on browsers, for example, supersampling or convolution.

All you need to do now is to add full-size picture to the canvas. Here is how the perfect case might look like. We leave the implementation of resizePixels behind the scenes.

function resizeImage(image, width, height) {
  var cIn = document.createElement('canvas');
  cIn.width = image.width;
  cIn.height = image.height;
  var ctxIn = cIn.getContext('2d');

  ctxIn.drawImage(image, 0, 0);
  var dataIn = ctxIn.getImageData(0, 0, image.width, image.heigth);
  var dataOut = ctxIn.createImageData(width, heigth);
  resizePixels(dataIn, dataOut);

  var cOut = document.createElement('canvas');
  cOut.width = width;
  cOut.height = height;
  cOut.getContext('2d').putImageData(dataOut, 0, 0);
  return cOut;
}

It is all so commonplace and mundane at first glance. But thank goodness, browsers’ creators do not let us bore themselves. Of course, such code can work in a few cases. The trap lies in the unexpected place.

First of all, let’s discuss why resizing is needed in the first place. For example, you have a task to reduce the size of photos before sending them to a server which would save the user’s traffic. It is more relevant for mobile devices with slow connection and paid traffic. And what photos are uploaded more often on the devices? It is those taken from the cameras of the same devices. For instance, camera resolution of an iPhone is 8 megapixel. But it is possible to capture 25-megapixel panoramic photo (it is even bigger on iPhone 6). Camera resolutions on Androids and WindowsPhones can be even higher. Here one learns about limitations of the mobile. Unfortunately, it is impossible to create a canvas that is more than 5 megapixel in iOS.

The reasons of Apple are pretty obvious. They have to make sure that their devices work properly with limited resources. Indeed, using the above-mentioned function the whole image fills the memory three times! Once, it is used for a buffer connected to the object Image where the image is unpacked into, a second time — canvas pixels, and a third time — a typified array in ImageData. It will take 8 × 3 × 4 = 96 megabyte of memory for an 8-megapixel image, and 300 – for a 25-megapixel image.

However, series of testing proved that problems are not confined exclusively to iOS. With some probability Chrome would start drawing several small images instead of one big image in Mac, while it would give a blank page in Windows.

But if there is no possibility to get all pixels simultaneously, perhaps it is possible to get them in parts? You can upload a picture to the canvas in several pieces. The width of each piece is equal to that of the original image, while the height is far smaller. At first, let’s add the first five megapixels, then we add the remained ones. Or you can choose two megapixels. It will reduce the memory usage even more. Fortunately, in contrast to the convolution two-channel resize, supersampling resize is one-channel i.e. you can not only get the image in portions, but also process it one portion a time. Memory will be used only for an Image element, a canvas (for example, 2 megapixels) and a typified array i.e. for a 8-megapixel image (8 + 2 + 2) × 4 = 48 megabyte which is two times less.

During the method implementation it was decided to measure how long it takes for each part. You can test it yourself here. Here is what we got for a picture with resolution 10800×2332 pixels (panorama from iPhone).

Browser Safari 8 Chrome 40 Firefox 35 IE 11
Image load 24 ms 27 28 76
Draw to canvas 1 348 278 387
Get image data 304 299 165 320
JS Resize 233 135 138 414
Put data back 1 1 3 5
Get image blob 10 16 21 19
Total 576 833 641 1243

Let’s take a look at the very curious table in more detail. Great news is that resize in Javascript is a well-developed feature. Of course, it is 1.7 times slower on Safari, than in Chrome and Firefox, and 3 times slower on IE, but in comparison to the uploading time of an image on browsers and receiving data it is not so much.

Another remarkable feature — there is no browser where a picture is decoded to the event image.onload. Decoding is postponed until the moment when it is really necessary, e.g. displaying on a screen or a canvas. An image is not decoded in Safari, even when it is put onto the canvas, since a canvas is also not displayed on the screen. Decoding happens only when pixels are extracted from the canvas.

In the table you can see the full time of drawing and data extraction, though in fact the operations are performed for every second megapixel, and the above-mentioned script shows the time of each iteration is counted independently. If you look at the indicators, you can clearly see that despite the fact that the overall time of data extraction for Safari, Chrome and IE are almost identical, in Safari almost the whole time is spent on the first calling in which the process of image decoding happens, while in Chrome and IE the time is equal for all the callings and indicate the overall sluggishness of data movement. The same applies to Firefox in less degree.

Presently this approach seems to have a great potential. Let’s test it on mobile devices. The testing team had HTC 8x (W), iPhone 4s (i4s), iPhone 5 (i5), Meizu MX4 Pro (A) on hand.

Browser Safari i4s Safari i5 Chrome i4s Chrome A Chrome A Firefox A IE W
Image load 517 ms 137 650 267 220 81 437
Draw to canvas 2 706 959 2 725 1 108 6 954 1 007 1 019
Get image data 678 250 734 373 543 406 1 783
JS Resize 2 939 1 110 96 320 491 458 418 2 299
Put data back 9 5 315 6 4 14 24
Get image blob 98 46 187 37 41 80 33
Total 6 985 2 524 101 002 2 314 8 242 2 041 5 700

What strikes the most is «outstanding» performance of Chrome in iOS. Indeed, up until recently all third-party browsers in iOS were able to work only with the versions that did not have jit-compilation. В iOS 8 an opportunity appeared to use jit, but Chrome did not manage to adapt to it as yet.

Another peculiarity is that the parameters of performance in Chrome and Android are radically different for a drawing time period, while all other aspects are almost identical. There are no errors in the table! Chrome can in fact perform differently. It was already mentioned that browsers are lazy to upload images. Thus nothing will stand in the way for a browser to release the memory taken by an image if it decides that a picture is not needed anymore. Obviously, when a picture is needed for the next session of drawing on a canvas, it should be decoded again. In the case, the picture was decoded 7 times. It is clearly indicated by the drawing time of independent chunks (remember, in the table only the overall time is displayed!). Under such conditions the decoding time is hard to predict.

Unfortunately, problems do not stop here. We must admit that the situation around Explorer is little confusing. There is size limits for each canvas side in 4096 pixels. And parts of the picture beyond the limits turn simply into transparent black pixels. While the limits of maximum canvas area are pretty simple to get around by cutting the picture horizontally and thus spare some memory, one has to work on the resize function pretty hard or merge the neighboring pieces in stripes which will only take more memory to bypass the width limit.

At this point, we decided to leave the thorny problem alone. There was also a completely crazy idea: to not only resize, but also decode jpeg for a client. Cons: only jpeg, the poor performance for Chrome in iOS will get even worse. Pros: predictability in Chrome in Android, no size restrictions, less memory required (no need to constantly copy to a canvas and back). Still, we had not chosen that version, although there is a  jpeg decoder in pure javascript.

Part 2. Let’s return to the beginning

You might remember how in the very beginning we had got a very good result after gradual decreasing in 2 times in a best case scenario, and blurry — in a worst case scenario. What if we will try to get rid of the worst-case version not changing the approach too much? Let us remind ourselves that the blurriness effect happens when on the last step it is necessary to decrease the image by just a little bit. What if we make the last step the first by reducing the image in a certain yet unknown proportion and afterwards strictly in 2 times? At the same time, it is necessary to take into account that the first step should not exceed a 5 megapixel area limit and 4096 pixels for a width. In this version the code gets obviously far simpler than in the case of a manual resize.

resize browser

On the left there is an image reduced in 4 steps, on the right – in 5 steps, and there is hardly any difference to see. Half the battle is won. Unfortunately, the difference between two and three steps (not to mention the difference between one and two steps) can still be seen pretty clearly:

image resize

Although now there is less blurring than was in the very beginning, we would even say that the image on the right (received in 3 steps) looks far nicer than the left one, which is too sharp.

One could certainly work on the resize a little bit trying to decrease the number of steps at the same time and bring the average step coefficient closer to two, it is important not to overdo. Browser restrictions do not allow to do something radically better. Let’s move to the next topic.

Part 3. Series of photos in a row

Resize is a pretty time-consuming operation. If one starts killing a mosquito with a bazook and resize the pictures one after the other, a browser will freeze and stop responding to user requests. It is recommended to use setTimeout after each resize step. But here another problem arises: if all images are resized simultaneously, the memory will be used simultaneously too. This can be prevented by organizing the queue. For example, one can launch the resize of the next image once the resize of the previous one is finished. But there is a more general solution which we preferred when the queue is created inside the resize function, not outside. This guarantees that two images will not be resized at the same time, even if the resize will be requested from different places simultaneously.

Here is a full example: it includes everything that was already in the second part plus the queue and timeouts before long operations implementation. We added a loading spinner to the page and now we can clearly see that if a browser hangs, it does for a short period of time. It is time to test it on mobile devices!

We must make a little digression and mention mobile Safari 8 (there is no data for other versions). The picture input works too slow and hangs for a few seconds. It is due to the fact that Safari creates a photo’s copy with a cut-off EXIF or generates a small preview which is shown directly in the input. While it is tolerable and almost unnoticeable for one photo, it can become hell for multiple-choice cases (it depends on the number of photos). And all the time the page is not aware whether photos are chosen or not, as well as whether the file selection dialog is opened at all.

Preparing for the worst we opened a page on the iPhone and chose 20 photos. After a little procrastination, Safari joyfully reported: A problem occurred with this webpage so it was reloaded. Second attempt — the same result. We envy you, our dear readers, the fact that for you the paragraph is just a brief text that will swiftly disappear from you consciousness, while for us it will always be associated with the night of pain and suffering.

So, Safari is not functioning too well. To fix it with the help of developer tools is not possible — there is nothing useful for memory usage here. Full of hope we opened a page in an iOS simulator — functions alright. We looked at the Activity Monitor — well, the memory is growing with each picture and is not being released. At least something. We started experimenting. To understand what experimenting in a simulator means: to see the memory leakage for one picture is not possible. It is still extremely hard to do it for 4-5 images. The best option is to choose 20 items. It is not possible to drag them or select using “shift”. You have to click it 20 times. Once you selected them, you have to look at the task manager and wonder whether the reduction of memory by 50 megabytes is a random fluctuation or you have done something wrong.

To be short, after a long series of trial and error we came to a simple, but very important conclusion: you have to empty everything you leave after yourself – as early as possible, using any available ways, and allocate the resources as late as possible. Relying on garbage collecting is out of question. If you create a canvas, eventually you have to nullify it (make it a size 1×1 pixels). In the case of a image you have to unload it (empty the space relocated) — at the end you have to unload it by assigning src=”about:blank”. Simply deleting it from DOM is not enough. If you open a file using URL.createObjectURL, you have to close using URL.revokeObjectURL.

After an intensive recoding of memory functions http://jsbin.com/pajamo/9/watch?js,output an old iPhone equipped with 512 Mb memory began processing 50 photos and more. Chrome and Opera on Android are now performing better (an unprecedented case). They managed to process 160 20-megapixel photos: slowly, but at least without breaks. It had a good impact on memory usage and desktop browser— IE, Chrome and Safari began consuming steadily no more than 200 megabyte for a tab during their work. Unfortunately, it did not help Firefox — it continues to spend almost a gigabyte for 25 testing images. We can not say anything about mobile Firefox and Dolphin in Android — it is impossible to choose several files there.

Part 4. Conclusion

As you can see, resizing pictures is very difficult, painful and fascinating at the same time. Some sort of Frankenstein: a hideous direct resize is implemented over and over again to get at least some degree of similarity to the original image. At the same time, you have to come around subtle (unwritten) restrictions of different platforms. All the same, a lot of individual combinations of initial and final size lead to a picture that is too blurry or sharp.

Browsers devour a lot of resources like crazy. Nothing is emptying itself automatically – magic does not work. In this sense it is even worse than working with compiled languages, where you doubtless have to empty resources. First of all, in js it is not obvious what should be emptied, secondly, it is not always possible. Nevertheless, pacifying browsers’ appetites of most of the browsers is quite possible.

We intentionally left out the part where we worked with EXIF. Almost all smartphones and cameras take photos from matrix in the same orientation and write down the real orientation in EXIF, that’s why it is important to send this information together with the reduced versions of pictures to a server. Fortunately, JPEG format is pretty simple and in the project we just transplant EXIF section with a source file to a final source even without dealing with it.

All that we learned and tested in the process of writing a resizing program intended for usage before file downloading for Uploadcare widget. The code cited in the article follows the narrative logic better than its final version. A lot of stuff concerning errors processing and browser support is left out. That’s why, if you want to try it yourself, you can find the source files here.

By the way, here is some additional statistics: using this technique, it took less than 2 minutes to load 80 photos reduced to 800×600 size through 3G network from iPhone 5. It would take 26 minutes to load the same original photos. So, obviously, it was worth it.

So, the case study has clearly shown you how much the method of the image resize influences the quality of the images. If you want the best quality webdesign and graphic design, contact Digital Services brilliant team of web developers and designers who can implement the best website design techniques for you to create a high-quality website.

Source: http://digitalservicescompany.com/

Spot.IM – Everywhere Social Network (Kết nối chat cho web)

Spot.IM enables you to implement a high-end community technology within 5 minutes, so you can host a vivid, live community with almost zero effort. Plus – no ad space is used in your current site’s real-estate.

Spot.IM is offering your users realtime conversation with direct messaging, subscription form, recommended articles and community trending content.

As a publisher, these benefits contribute to your site’s retention metrics; as users are coming back more often, watching more pages and staying much longer in your website.

Features

As part of our spot we offer a variety of features, so users and spot owner can enjoy the best experience:

  • Language support – we support 8 languages (English, Portuguese, Spanish, Russian, German, Korean, Arabic and Hebrew).
  • Smart links – users can see the links in preview modes, with thumbnail and text.
  • Branding your Spot – Why use a generic chat? when you can brand your Spot with your site’s logo and colors. Just go to Spot.IM and brand your Spot in seconds.
  • Mentions – your community members can mention each other in the spot with just a (at). So that the mentioned user gets a mobile/email alert even if he or she is offline.
  • DirectSpot – if someone in your community wants to talk in private he can do it with the personal mode. The user gets a mobile/email alert even if he or she is offline.
  • Moderation – automatic word and link filtering in group chat.
  • Full media sharing – your community users can share any kind of media they like, from photos to videos, and all the media they share is stored on the your Spot’s gallery.
  • Like and shareSpot.IM enables your community members to like and share each other’s messages.
  • PinBoard – choose the context of the conversation and pin it to the top of the Spot so everybody knows what the community’s talking about (Available for chat hosts and site owners only).
  • Gather – have something to tell your community members? as spot owner you can use the gathering feature and invite all your users to the spot to talk about your big news.
  • Online and typing – someone is online in the spot? Or is someone typing? We enable users in the spot see what’s going on in real time.
  • Social plugin – we offer users to login with their social persona Via Facebook, twitter and Google+

For more information please visit our website – Spot.IM.

Source: https://wordpress.org/plugins/spotim/

CSS Media Queries for All Devices and Browsers (Including IE7 and IE8)

In CSS3, web developers/designers can define a media type such as screen or print, and specify the look of the content by setting conditions such as width, height, or orientation. A CSS media query combines a media type and a condition that shows how web content will appear on a particular device.

CSS Media queries are an excellent way to deliver different styles to different devices, providing the best experience for each type of user. A part of the CSS3 specification, CSS media queries expand the role of the media attribute that controls how your styles are applied. For example, it’s been a common practice for years to use separate style sheet for printing web pages by specifyingmedia=”print”.

CSS Media queries take this idea to the next level by allowing developers target styles based on a number of device properties, such as screen width, orientation, and so on. Following table demonstrates CSS media queries for all browsers in action. They all show the same web page as it’s viewed in a desktop browser, tablet or an iPod touch.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/* Smartphones (portrait and landscape) ----------- */
@media only screen
and (min-device-width : 320px)
and (max-device-width : 480px) {
/* STYLES GO HERE */
}
 
/* Smartphones (landscape) ----------- */
@media only screen
and (min-width : 321px) {
/* STYLES GO HERE */
}
 
/* Smartphones (portrait) ----------- */
@media only screen
and (max-width : 320px) {
/* STYLES GO HERE */
}
 
/* iPads (portrait and landscape) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px) {
/* STYLES GO HERE */
}
 
/* iPads (landscape) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : landscape) {
/* STYLES GO HERE */
}
 
/* iPads (portrait) ----------- */
@media only screen
and (min-device-width : 768px)
and (max-device-width : 1024px)
and (orientation : portrait) {
/* STYLES GO HERE */
}
 
/* Desktops and laptops ----------- */
@media only screen
and (min-width : 1224px) {
/* STYLES GO HERE */
}
 
/* Large screens ----------- */
@media only screen
and (min-width : 1824px) {
/* STYLES GO HERE */
}
 
/* iPhone 5 (portrait &amp; landscape)----------- */
@media only screen
and (min-device-width : 320px)
and (max-device-width : 568px) {
/* STYLES GO HERE */
}
 
/* iPhone 5 (landscape)----------- */
@media only screen
and (min-device-width : 320px)
and (max-device-width : 568px)
and (orientation : landscape) {
/* STYLES GO HERE */
}
 
/* iPhone 5 (portrait)----------- */
@media only screen
and (min-device-width : 320px)
and (max-device-width : 568px)
and (orientation : portrait) {
/* STYLES GO HERE */
}

Media Queries Support

CSS Media queries are supported in Internet Explorer (IE) 9+, Firefox 3.5+, Safari 3+, Opera 7+, as well as on smartphones and other screen-based devices.

Although older versions of IE don’t support media queries, still there is a way you can make it work.

Even though everyone thinks that earlier versions of IE are already extinct, there is a great amount of people using them, her are some stats:

1 Chrome 37 24.85%
2 Safari 7 10.60%
3 Firefox 32 8.03%
4 Internet Explorer 11 7.31%
5 Chrome 36 5.62%
6 Android 4 3.94%
7 Firefox 31 3.91%
8 Internet Explorer 8 3.66%
9 Internet Explorer 9 3.08%
10 Internet Explorer 10 2.34%

Normally IE5 to IE8 do not support CSS3 Media Query. But at least IE8 should support CSS3 Media Query and that is very important for cross-browser responsive web design. Here I will tell you how you can solve the CSS3 Media Query issues for IE.

Here is a great jQuery plugin called css3-mediaqueries. It’s very easy to use.

Download jQuery plugin and include downloaded script just before the </body> like this:

1
<script src="js/css3-mediaqueries.js"></script>

Or you can use the following way to include the script.

1
2
3
4
<!-- css3-mediaqueries.js for IE less than 9 -->
<!-- [if lt IE 9]>
<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->

Then write media query in style sheet and check it in IE. It will work nicely with IE8, IE7, even in older versions IE6 or IE5.

Notes

It doesn’t work on @import’edstylesheets

Write media query the following way:

1
2
3
4
@media screen and (min-width: 980px)
{
/* CSS Document */
}

Use keyword ‘and’ in query (‘or’ is not supported).

One thing must be noted is that the “screen” is necessary:

1
2
@media (min-width: 481px) { /* ... */ } will not work, it must be
@media screen and (min-width: 481px) { /* ... */ }

* * *

Thats’s it, if you have some other ideas on how to use CSS media queries feeel free to drop your ideas in the comments below. Have a great day.

Source: http://blog.templatemonster.com/

jquery-device-detect

//touch/mobile detection
if (
navigator.userAgent.match(/Phone/i) ||
navigator.userAgent.match(/DROID/i) ||
navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPod/i) ||
navigator.userAgent.match(/BlackBerry/) ||
navigator.userAgent.match(/Windows Phone/i) ||
navigator.userAgent.match(/ZuneWP7/i) ||
navigator.userAgent.match(/IEMobile/i)
){ var mobile_device = true; var touch_device = true; }
//touch/tablet detection
if (
navigator.userAgent.match(/Tablet/i) ||
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/Kindle/i) ||
navigator.userAgent.match(/Playbook/i) ||
navigator.userAgent.match(/Nexus/i) ||
navigator.userAgent.match(/Xoom/i) ||
navigator.userAgent.match(/SM-N900T/i) || //Samsung Note 3
navigator.userAgent.match(/GT-N7100/i) || //Samsung Note 2
navigator.userAgent.match(/SAMSUNG-SGH-I717/i) || //Samsung Note
navigator.userAgent.match(/SM-T330NU/i) //Samsung Tab 4
){ var tablet_device = true; var touch_device = true; }
//get ready
$(“document”).ready( function(){
if(mobile_device){
$(“#device_icon”).addClass(“icon-mobile-portrait”);
$(“#user_agent”).html(navigator.userAgent);
}
if(tablet_device){
$(“#device_icon”).addClass(“icon-tablet-landscape”);
$(“#user_agent”).html(navigator.userAgent);
}
if(!mobile_device && !tablet_device){
$(“#device_icon”).addClass(“icon-monitor”);
$(“#user_agent”).html(navigator.userAgent);
}
}); //eof ready

20 font Việt chữ đẹp thường dùng thiệp cưới wedding font (mã VNI)

font 1 font 2

Vni 11 Springtime2
Vni 12 Alex
Vni 13 Annabelle
Vni 14 AlexBrush
VNI 15 Chops Normal
Vni 16 Machina
VNI 17 Sandy
Vni 18 Mandalay
Vni 19 Walt Disney
Vni 20 University
Vni 21 Scrap Cursive
VNI 22 JackieO
Vni 23 Qwigley
VNI 24 Love
Vni 25 Ambiance BT Swash
VNI 26 Saliere
VNI 27 Bendigo
VNI 28 Zirkon
Vni 29 BrushMe
Vni 30 Shishoni Brush

Giải nén: inhaiyen

JavaScript Syntax

JavaScript Syntax

There are three versions of the drawImage method.

To simply draw the image on the canvas:

context.drawImage(img,x,y);

To draw the image on the canvas, and resize the image:

context.drawImage(img,x,y,width,height);

To draw the clipped image part on the canvas:

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

The following image shows the relation between the image and clipped image and canvas.

null

Image reference: http://www.w3.org/TR/2dcontext/

Parameter Values

Parameter Description
img image, canvas, or video element to use
sx Optional. The x coordinate where to start clipping
sy Optional. The y coordinate where to start clipping
swidth Optional. The width of the clipped image
sheight Optional. The height of the clipped image
x The x coordinate where to place the image on the canvas
y The y coordinate where to place the image on the canvas
width Optional. The width of the image to use
height Optional. The height of the image to use

Normal Paint

drawImage(Image, dx, dy)

This function takes in three parameters: an Image object, and x and y values representing the top-left corner location to start painting the image on the canvas.

To draw our spaceship image at the 0,0 location (the top-left corner) of the canvas:

context.drawImage(spaceShip, 0, 0);

To draw another copy at 50,50, we would simply make the same call but change the location:

context.drawImage(spaceShip, 50, 50);

Resize

To paint and scale drawn images, we can also pass parameters into the drawImage() function.

The second version of drawImage() takes in an extra two parameters:

drawImage(Image, dx, dy, dw, dh)

dw and dh represent the width and height source image will be painted.

If we want to scale the image, we would use the following code:

context.drawImage(spaceShip, 0, 0,64,64);

Draw Image Part

The third version drawImage() allows us to draw an arbitrary rectangle of data from image.

The structure of the parameters for this third version of the drawImage() function looks like this:

drawImage(Image, sx, sy, sw, sh, dx, dy, dw, dh)

sx and sy represent the “source positions” to start copying the source image. sw and sh represent the width and height of the rectangle starting at sx and sy.

That rectangle will be copied at “destination” positions dx and dy.

dw and dh represent the newly scaled width and height for the image.

Nguồn: http://www.java2s.com/

Những tính năng sẽ mất đi khi nâng cấp từ Windows 7,8 lên Windows 10

Windows 10 sẽ được chính thức phát hành vào ngày 29/7 và bất kì ai đang dùng Windows 7 hoặc Windows 8.1 bản quyền đều được cập nhật miễn phí lên phiên bản mới này.

Bên cạnh hàng loạt tính năng mới vô cùng thú vị, Windows 10 cũng sẽ bỏ đi một số chức năng của các thế hệ Windows cũ, chẳng hạn như Windows Media Center, gadget, không còn hỗ trợ đĩa mềm… Đặc biệt, người dùng Windows 10 Home sẽ không được phép tắt chế độ tự động cập nhật của hệ điều hành, chỉ người dùng Pro và Enterprise mới có lựa chọn đó mà thôi. Bên dưới là chi tiết những tính năng không còn tồn tại trong Windows 10, mời anh em xem qua.

Windows Media Center

Microsoft nói rõ rằng phần mềm giải trí này sẽ không còn được cung cấp trong Windows 10. Với một số người dùng thì hiện đây vẫn là một trong những giải pháp thường dùng để nghe nhạc và xem phim, tuy nhiên bây giờ chúng ta đã có khá nhiều phần mềm miễn phí khác như VLC, Media Player Classic cũng có chức năng tương tự, thậm chí còn hơn nên các bạn có thể chuyển sang dùng những app đó.

Khả năng phát đĩa DVD bằng Windows Media Player

Tương tự như trên, bạn có thể xài VLC hoặc Media Player Classic để chơi đĩa DVD, không còn cần đến Windows Media Player nữa nên việc Microsoft bỏ tính năng này cũng không có gì nghiêm trọng. Với hai phần mềm mà mình đề xuất, các bạn còn có thể tinh chỉnh chất lượng ảnh cũng như âm thanh cho đẹp hơn, hay hơn, thứ mà Windows Media Player không làm được.

Desktop Gadget

Gadget là những ứng dụng nhỏ gắn lên desktop được giới thiệu lần đầu trong Windows Vista. Một số gadget khá hữu ích, ví dụ như gadget ghi chú, đồng hồ thế giới, tuy nhiên phần lớn những phần mềm dạng này chiếm nhiều tài nguyên hệ thống và cũng không còn nhiều người sử dụng. Chính vì vậy mà Microsoft quyết định sẽ không còn hỗ trợ nó trong Windows 10.

Windows 10 Home không thể tắt tự động cập nhật

Nếu như bạn xài Windows 10 Home, bạn sẽ phải cập nhật và cài đặt các bản update từ Microsoft một cách tự động, không còn tùy chọn để tắt đi. Chỉ Windows 10 Pro và Enterprise mới được cung cấp lựa chọn đó mà thôi. Điều này có thể sẽ làm phiền nhiều anh em khi mà mỗi lần cập nhật thì Windows đều yêu cầu khởi động lại máy.

Bỏ game Solitaire, Minesweeper và Hearts

Những trò chơi cổ điển này sẽ được thay thế bằng Microsoft Solitaire Collection và Microsoft Minesweeper mới hơn nên cũng không lo lắm.

Không hỗ trợ đĩa mềm

Còn anh em nào dùng đĩa mềm để lưu dữ liệu không? Nếu có, bạn sẽ phải mua ổ mềm riêng và cài driver từ nhà sản xuất chứ mặc định Windows 10 không còn hỗ trợ loại thiết bị lưu trữ này nữa.

Windows Live Essentials

Nếu bạn đang cài Windows Live Essentials, bao gồm các công cụ để viết ghi chú, chỉnh văn bản đơn giản, check mail và dựng phim, “ứng dụng OneDrive sẽ bị gỡ bỏ và thay thế bằng một phiên bản inbox của OneDrive”. Chưa rõ phiên bản inbox mà Microsoft nhắc tới là gì.

Only allow input number for google chrome android

HTML:

<input type=”text” id=”test” />

JAVASCRIPT

// utility jQuery plugins
$.fn.blockInput = function (options)
{
// find inserted or removed characters
function findDelta(value, prevValue)
{
var delta = ”;

for (var i = 0; i < value.length; i++) {
var str = value.substr(0, i) +
value.substr(i + value.length – prevValue.length);

if (str === prevValue) delta =
value.substr(i, value.length – prevValue.length);
}

return delta;
}

function isValidChar(c)
{
return new RegExp(options.regex).test(c);
}

function isValidString(str)
{
for (var i = 0; i < str.length; i++)
if (!isValidChar(str.substr(i, 1))) return false;

return true;
}

this.filter(‘input,textarea’).on(‘input’, function ()
{
var val = this.value,
lastVal = $(this).data(‘lastVal’);

// get inserted chars
var inserted = findDelta(val, lastVal);
// get removed chars
var removed = findDelta(lastVal, val);
// determine if user pasted content
var pasted = inserted.length > 1 || (!inserted && !removed);

if (pasted)
{
if (!isValidString(val)) this.value = lastVal;
}
else if (!removed)
{
if (!isValidChar(inserted)) this.value = lastVal;
}

// store current value as last value
$(this).data(‘lastVal’, this.value);
}).on(‘focus’, function ()
{
$(this).data(‘lastVal’, this.value);
});

return this;
};

$(‘#test’).blockInput({ regex: ‘[0-9A-Z]’ });

Nguồn: http://jsfiddle.net/zminic/8Lmay/