Tumblelog by Soup.io
Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

March 31 2015

07:39
05:33
Bubi Au Yeung x Crazy Label Whispering Spirit Vinyl Set
05:07
Super7 Wondercon Exclusive Molten Magma Fossilla
05:01
Merging Responsive Web Design Ideas for Desktop & Mobile
04:45
J*RYU x Kidrobot F.A.D. Dunny?
04:12
Gary Ham x Pobber Toys - Autumn Stag Pre-Order
03:47
Yoskay Yamamoto x Mighty Jaxx Black Edition Wish Upon Me

March 30 2015

23:50
How GitHub Apparently Ended Up In The Crosshairs Of Chinese Hackers
21:40
21:36
21:35
21:35
20:54

You want to cut aid? It’s on.

Congress’s budget proposals may have been submitted, but it will still be months until we know the final budget numbers. As much as we hate it, the global health and poverty-fighting programs we fight for every day always come under fire during this time and bad things happen when we don’t take action….

1. When budget proposals are in, but nothing is final yet:
h9dly

2. When people don’t think life-saving programs are important to fund:
h9dbf

3. And sometimes some of those people are decision-makers:
jizzd

4. Even when Ryan Gosling proposes cuts it sounds awful:
h9d6h

5. Despite necessary cuts across the board, this year just isn’t the year for cuts on life-saving programs:
h9cx2

6. Which makes absolutely no sense:
h9cva

7. When it leaves us all so puzzled:
h9coc

8. When all you think you can do is prepare for the worst:
h9cd89. But there’s actually something you can do:

jj2m5

Fight for global health and life-saving programs by signing the petition to protect them in the budget here.

19:19

Programming With Yii2: Localization With I18n

Final product image What You'll Be Creating

If you're asking, "What's Yii?" check out my earlier tutorial:  Introduction to the Yii Framework , which reviews the benefits of  Yii and includes an overview of what's new in Yii 2.0, released October 12th, 2014.

In this Programming With Yii2 series, I'm guiding readers in use of the newly upgraded Yii2 Framework for PHP. In part one, we set up Yii2 locally, built a Hello World application, set up a remote server and used Github to deploy our code. In part two, we learned about Yii's implementation of its Model View Controller architecture and how to build web pages and forms that collect and validate data. In part three, we used Yii's database and active record capabilities to automate code generation for a basic web application. And, in part four, we learned how to integrate user registration.

In this tutorial, I'm going to show you how to make use of Yii's built-in I18n internationalization support to make your application ready for translation into a number of languages.

For these examples, we'll continue to imagine we're building a framework for posting simple status updates, e.g. our own mini-Twitter.

What's I18n?

According to Wikipedia, I18n is a numeronym for Internationalization:

18 stands for the number of letters between the first i and last n in internationalization, a usage coined at DEC in the 1970s or 80s.

With I18n, all of the text strings displayed to the user from the application are replaced by function calls which can dynamically load translated strings for any language the user selects.

The Goals of Internationalization

When building a web application, it's useful to think globally from the beginning. Does your app need to work in other languages for users from different countries? If so, then implementing I18n from the beginning will save you a lot of time and headaches later.

In our case, the Yii Framework provides built-in support for I18n so it's relatively easy to build support in for I18n as you go along.

How I18n Works

I18n operates by replacing all references to text displayed to the user with function calls that provide translation when needed. 

For example, here's what the attribute field names in the Status model look like before I18n:

Providing translated versions of the code would become very complicated. Non-technical translators would have to translate code in place, likely breaking syntax.

Here's what the same code looks like with I18n:

Yii:t() is a function call that checks what language is currently selected and displays the appropriate translated string. The 'app' parameter refers to a section of our application. Translations can be optionally organized according to various categories. But where do these translated strings appear?

The default language, in this case English, is written into the code, as shown above. Language resource files are lists of arrays of strings whose key is the default language text, e.g. 'Message' or 'Permissions'—and each file provides translated text values for their appropriate language.

Here's an example of our completed Spanish translation file, language code "es". The Yii:t() function uses this file to find the appropriate translation to display:

While this looks time-consuming, Yii provides scripts to automate the generation and organization of these file templates.

By separating the text from the code, we make it easier for non-technical multi-lingual experts to translate our applications for us—without breaking the code.

I18n also offers specialized functions for translating time, currency, plurals et al. I won't go into the detail of these in this tutorial. 

Configuring I18n Support

Unfortunately, the Yii2 documentation for I18n is not yet very descriptive, and it was difficult to find working, step by step examples. Luckily for you, I'm going to walk you through what I've learned from scouring the docs and the web. I found The Code Ninja's I18n example and the Yii2 Definitive Guide on I18n helpful, and Yii contributor Alexander Makarov offered me some assistance as well.

Generating the I18n Configuration File

We're using the Yii2 basic application template for our demonstration application. This places our codebase below the /hello root directory. Yii's configuration files in /hello/config/* are loaded whenever page requests are made. We'll use Yii's I18n message scripts to build out a configuration file for I18n in the common/config path.

From our codebase root, we'll run the Yii message/config script:

This generates the following file template which we can customize:

I'm customizing the file as follows. I move messagePath up to the top and customize sourcePath and messagePath. I am also specifying the languages I want my application to support besides English—in this case Spanish (es), German (de), Italian (it) and Japanese (ja). Here's a list of all the I18n language codes.

In the next step, we'll run Yii's extract script which will scan all the code in the sourcePath tree to generate default string files for all the labels used in our code. I'm customizing sourcePath to scan the entire code tree. I'm customizing messagePath to generate the resulting files in common/messages.

You'll see Yii scanning all of your code files:

When it completes, you'll see something like this in your codebase:

Yii2 Localization with I18n Directory Paths

Activating I18n and Selecting a Language

In the common configuration file, /hello/config/web.php, we're going to tell Yii about our new language support. I'll make Spanish my default language:

But there's still more to do. We have to make our code I18n aware.

Using Yii's Gii Code Generator With I18n

In part three of this series, we used Yii's database and active record capabilities to automate code generation. But we did not activate I18n, so all of our code had text strings embedded. Let's redo this.

We return to Gii, likely http://localhost:8888/hello/gii in your browser, and re-run the model and controller generators with I18n activated.

Here's an example of generating the Meeting model code with I18n activated. Notice that we specify "app" for our Message Category. We're placing all of our text strings in one app category file. 

Yii2 Gii Code Generator Status Model for I18n

Let's do the same for the CRUD generation for controllers and views:

Yii2 Gii Code Generator for Status CRUD With I18n

If you browse the generated code in models, controllers and views you'll see the text strings replaced with the Yii:t('app',...) function:

Making Static Views I18n Ready

Because we generate a number of views in our application by hand or in HTML, we need to manually convert these to use I18n. For example, our navigation bar in /views/layouts/main.php and our home page in /views/site/index.php both need to be edited by hand. 

Here's the navigation bar before I18n:

Here's the navigation bar after I18n:

Here's a fragment of the home page content from index.php after I18n—much of the HTML has been replaced by PHP calls to Yii::t():

Translating Your Message Files

Take a look at our Spanish message file, /common/messages/es/frontend.php. It's a long list of empty array values:

For the purposes of filling in our Spanish language translations for this tutorial, I'll use Google Translate. Tricky, huh?

Yii2 I18n Using Google Translator to Fill Message Files

Then, we'll do some cut and paste with those translations back into the message file. 

When we visit the Application home page, you'll see the Spanish version—nice, huh?

Yii2 I18n Our App Home Page in Spanish

Here's the Create Status form:

Yii2 I18n Create a Status Update in Spanish Form

If I want to switch back to English, I just change the configuration file, /config/web.php, back to English:

You'll also notice as you proceed that replacing strings in JavaScript has its own complexities. I haven't explored it myself, but the Yii 1.x JsTrans extension may provide a useful guideline for supporting this.

Going Further With I18n

Ultimately, we may want to translate our application into a number of languages. I've written a new tutorial called Using the Google Translate API to Localize Your I18n App (Tuts+) which automatically translates your application into a variety of languages. If it's not published yet, it will be published soon (check my instructor page). Of course, this just provides base translations. You may want to hire professional translators to tune the files afterwards.

Some applications allow users to select their native language so that when they log in, the user interface automatically translates for them. In Yii, setting the $app->language variable does this:

Other applications, like JScrambler.com below, leverage the URL path to switch languages. The user just clicks the language prefix they want, e.g. "FR", and the app is automatically translated: 

JScrambler Dynamic Language Paths

Note: Read my recent introduction to JScrambler to find out more —it's a pretty useful service.

Yii's URL Manager can provide this type of functionality as well. I will probably implement these features in a future tutorial in this Yii2 series when I focus on Routing.

What's Next?

I hope you're excited about the power of I18n and the benefits of using the Yii Framework over vanilla PHP. Watch for upcoming tutorials in our Programming With Yii2 series.

If you'd like to know when the next Yii2 tutorial arrives, follow me @reifman on Twitter or check my instructor page. My instructor page will include all the articles from this series as soon as they are published. You can also email me at my Lookahead Consulting website.

Related Links

18:57
Reactor-88s Custom Corner: Shiffa
17:27
What It Will Be Like To Buy An Apple Watch
17:25

How to Use Android Media Effects With OpenGL ES

Android's Media Effects framework allows developers to easily apply lots of impressive visual effects to photos and videos. As the framework uses the GPU to perform all its image processing operations, it can only accept OpenGL textures as its input. In this tutorial, you are going to learn how to use OpenGL ES 2.0 to convert a drawable resource into a texture and then use the framework to apply various effects to it.

Prerequisites

To follow this tutorial, you need to have:

  • an IDE that supports Android application development. If you don't have one, get the latest version of Android Studio from the Android Developer website.
  • a device that runs Android 4.0+ and has a GPU that supports OpenGL ES 2.0.
  • a basic understanding of OpenGL.

1. Setting Up the OpenGL ES Environment

Step 1: Create a GLSurfaceView

To display OpenGL graphics in your app, you have to use a GLSurfaceView object. Like any other View, you can add it to an Activity or Fragment by defining it in a layout XML file or by creating an instance of it in code.

In this tutorial, you are going to have a GLSurfaceView object as the only View in your Activity. Therefore, creating it in code is simpler. Once created, pass it to the setContentView method so that it fills the entire screen. Your Activity's onCreate method should look like this:

Because the Media Effects framework only supports OpenGL ES 2.0 or higher, pass the value 2 to the setEGLContextClientVersion method.

To make sure that the GLSurfaceView renders its contents only when necessary, pass the value RENDERMODE_WHEN_DIRTY to the setRenderMode method.

Step 2: Create a Renderer

A GLSurfaceView.Renderer is responsible for drawing the contents of the GLSurfaceView.

Create a new class that implements the GLSurfaceView.Renderer interface. I am going to call this class EffectsRenderer. After adding a constructor and overriding all the methods of the interface, the class should look like this:

Go back to your Activity and call the setRenderer method so that the GLSurfaceView uses the custom renderer.

Step 3: Edit the Manifest

If you plan to publish your app on Google Play, add the following to AndroidManifest.xml:

This makes sure that your app can only be installed on devices that support OpenGL ES 2.0. The OpenGL environment is now ready.

2. Creating an OpenGL Plane

Step 1: Define Vertices

The GLSurfaceView cannot display a photo directly. The photo has to be converted into a texture and applied to an OpenGL shape first. In this tutorial, we will be creating a 2D plane that has four vertices. For the sake of simplicity, let's make it a square. Create a new class, Square, to represent the square.

The default OpenGL coordinate system has its origin at its center. As a result, the coordinates of the four corners of our square, whose sides are two units long, will be:

  • bottom left corner at (-1, -1)
  • bottom right corner at (1, -1)
  • top right corner at (1, 1)
  • top left corner at (-1, 1)

All the objects we draw using OpenGL should be made up of triangles. To draw the square, we need two triangles with a common edge. This means that the coordinates of the triangles will be:

triangle 1: (-1, -1), (1, -1), and (-1, 1)
triangle 2: (1, -1), (-1, 1), and (1, 1)

Create a float array to represent these vertices.

To map the texture onto the square, you need to specify the coordinates of the vertices of the texture. Textures follow a coordinate system in which the value of the y-coordinate increases as you go higher. Create another array to represent the vertices of the texture.

Step 2: Create Buffer Objects

The arrays of coordinates need to be converted into byte buffers before OpenGL can use them. Let's declare these buffers first.

Write the code to initialize these buffers in a new method called initializeBuffers. Use the ByteBuffer.allocateDirect method to create the buffer. Because a float uses 4 bytes, you need to multiply the size of the arrays with the value 4.

Next, use ByteBuffer.nativeOrder to determine the byte order of the underlying native platform, and set the order of the buffers to that value. Use the asFloatBuffer method to convert the ByteBuffer instance into a FloatBuffer. After the FloatBuffer is created, use the put method to load the array into the buffer. Finally, use the position method to make sure that the buffer is read from the beginning.

The contents of the initializeBuffers method should look like this:

Step 3: Create Shaders

It's time to write your own shaders. Shaders are nothing but simple C programs that are run by the GPU to process every individual vertex. For this tutorial, you have to create two shaders, a vertex shader and a fragment shader.

The C code for the vertex shader is:

The C code for the fragment shader is:

If you already know OpenGL, this code should be familiar to you because it is common across all platforms. If you don't, to understand these programs you must refer to the OpenGL documentation. Here's a brief explanation to get you started:

  • The vertex shader is responsible for drawing the individual vertices. aPosition is a variable that will be bound to the FloatBuffer that contains the coordinates of the vertices. Similarly, aTexPosition is a variable that will be be bound to the FloatBuffer that contains the coordinates of the texture. gl_Position is a built-in OpenGL variable and represents the position of each vertex. The vTexPosition is a varying variable, whose value is simply passed on to the fragment shader.
  • In this tutorial, the fragment shader is responsible for coloring the square. It picks up colors from the texture using the texture2D method and assigns them to the fragment using a built-in variable named gl_FragColor.

The shader code needs to be represented as String objects in the class.

Step 4: Create a Program

Create a new method called initializeProgram to create an OpenGL program after compiling and linking the shaders.

Use glCreateShader to create a shader object and return a reference to it in the form of an int. To create a vertex shader, pass the value GL_VERTEX_SHADER to it. Similarly, to create a fragment shader, pass the value GL_FRAGMENT_SHADER to it. Next use glShaderSource to associate the appropriate shader code with the shader. Use glCompileShader to compile the shader code.

After compiling both shaders, create a new program using glCreateProgram. Just like  glCreateShader, this too returns an int as a reference to the program. Call glAttachShader to attach the shaders to the program. Finally, call glLinkProgram to link the program.

Your method and the associated variables should look like this:

You might have noticed that the OpenGL methods (the methods prefixed with gl) belong to the class GLES20. This is because we are using OpenGL ES 2.0. If you wish to use a higher version, then you will have to use the classes GLES30 or GLES31.

Step 5: Draw the Square

Create a new method called draw to actually draw the square using the vertices and shaders we defined earlier.

Here's what you need to do in this method:

  1. Use glBindFramebuffer to create a named frame buffer object (often called FBO).
  2. Use glUseProgram to start using the program we just linked.
  3. Pass the value GL_BLEND to glDisable to disable the blending of colors while rendering.
  4. Use glGetAttribLocation to get a handle to the variables aPosition and aTexPosition mentioned in the vertex shader code.
  5. Use glGetUniformLocation to get a handle to the constant uTexture mentioned in the fragment shader code.
  6. Use the glVertexAttribPointer to associate the aPosition and aTexPosition handles with the verticesBuffer and the textureBuffer respectively.
  7. Use glBindTexture to bind the texture (passed as an argument to the draw method) to the fragment shader.
  8. Clear the contents of the GLSurfaceView using glClear.
  9. Finally, use the glDrawArrays method to actually draw the two triangles (and thus the square).

The code for the draw method should look like this:

Add a constructor to the class to initialize the buffers and the program at the time of object creation.

3. Rendering the OpenGL Plane and Texture

Currently, our renderer does nothing. We need to change that so that it can render the plane we created in the previous steps.

But first, let us create a Bitmap. Add any photo to your project's res/drawable folder. The file I am using is called forest.jpg. Use the BitmapFactory to convert the photo into a Bitmap object. Also, store the dimensions of the Bitmap object in separate variables.

Change the constructor of the EffectsRenderer class so that it has the following contents:

Create a new method called generateSquare to convert the bitmap into a texture and initialize a Square object. You will also need an array of integers to hold references to the OpenGL textures. Use glGenTextures to initialize the array and glBindTexture to activate the texture at index 0.

Next, use glTexParameteri to set various properties that decide how the texture is rendered:

  • Set GL_TEXTURE_MIN_FILTER (the minifying function) and the GL_TEXTURE_MAG_FILTER (the magnifying function) to GL_LINEAR to make sure that the texture looks smooth, even when it's stretched or shrunk.
  • Set GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T to GL_CLAMP_TO_EDGE so that the texture is never repeated.

Finally, use the texImage2D method to map the Bitmap to the texture. The implementation of the generateSquare method should look like this:

Whenever the dimensions of the GLSurfaceView change, the onSurfaceChanged method of the Renderer is called. Here's where you have to call glViewPort to specify the new dimensions of the viewport. Also, call glClearColor to paint the GLSurfaceView black. Next, call generateSquare to reinitialize the textures and the plane.

Finally, call the Square object's draw method inside the onDrawFrame method of the Renderer.

You can now run your app and see the photo you had chosen being rendered as an OpenGL texture on a plane.

4. Using the Media Effects Framework

The complex code we wrote until now was just a prerequisite to use the Media Effects framework. It's now time to start using the framework itself. Add the following fields to your Renderer class.

Initialize the effectContext field by using the EffectContext.createWithCurrentGlContext. It's responsible for managing the information about the visual effects inside an OpenGL context. To optimize performance, this should be called only once. Add the following code at the beginning of your onDrawFrame method.

Creating an effect is very simple. Use the effectContext to create an EffectFactory and use the EffectFactory to create an Effect object. Once an Effect object is available, you can call apply and pass a reference to the original texture to it, in our case it is textures[0], along with a reference to a blank texture object, in our case it is textures[1]. After the apply method is called, textures[1] will contain the result of the Effect.

For example, to create and apply the grayscale effect, here's the code you have to write:

Call this method in onDrawFrame and pass textures[1] to the Square object's draw method. Your onDrawFrame method should have the following code:

The release method is used to free up all resources held by an Effect. When you run the app, you should see the following result:

You can use the same code to apply other effects. For example, here's the code to apply the documentary effect:

The result looks like this:

Some effects take parameters. For instance, the brightness adjustment effect has a brightness parameter which takes a float value. You can use setParameter to change the value of any parameter. The following code shows you how to use it:

The effect will make your app render the following result:

Conclusion

In this tutorial, you have learned how to use the Media Effects Framework to apply various effects to your photos. While doing so, you also learned how to draw a plane using OpenGL ES 2.0 and apply various textures to it.

The framework can be applied to both photos and videos. In case of videos, you simply have to apply the effect to the individual frames of the video in the onDrawFrame method.

You have already seen three effects in this tutorial and the framework has dozens more for you to experiment with. To know more about them, refer to the Android Developer's website.






17:09
De Korner x AndrewBell - WonderCon Exclusive Last Knight Grayscale
16:58

It’s a bird, it’s a plane, no…it’s #ONEderWoman!

Here at ONE we believe that there are a lot of amazing girls and women all over the globe who are doing incredible things to make our world a better place. Whether it’s empowering women in their local communities, or influencing change on an international level, there are some seriously rock-star girls and women out there, who are breaking ceilings, pushing boundaries, and shattering stereotypes—and we want to highlight them on our Girls and Women page.

That’s why we’ve created a new section of our webpage, in which we give a shout-out to a #ONEderWoman of the week. These girls and women can come from anywhere in the world and can be any age—the only requirement is that they are doing something awesome for their community or for the world. We feel like it’s extremely important to shine a spotlight on all of the real life super heroes out there and thank them for their amazing and inspiring work. As Maya Angelou once said, “how important it is for us to recognize and celebrate our heroes and she-roes!”

So, if you know anybody who you consider a she-roe, please nominate her for our #ONEderWoman of the week via Twitter or email! Just provide us with a brief description and a link for where we can find more information and you’re all set!

ONEder-woman-image-1
16:26
Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.