Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ii:labs:s2:02:tasks:01 [2022/04/14 20:17]
radu.mantu
ii:labs:s2:02:tasks:01 [2024/03/17 18:24] (current)
florin.stancu
Line 1: Line 1:
-==== 01. [??pReading the frame buffer ​====+==== 01. [30pMinor Design Changes ​====
  
-By now, we all know that not all files are backed by a storage device. While some reside on your HDD/SSD, Linux mounts virtual filesystems such as [[https://​www.kernel.org/​doc/​html/​latest/​filesystems/​proc.html|procfs]] or [[https://​www.kernel.org/​doc/​html/​latest/​filesystems/​sysfs.html|sysfs]]. Today we are going to look at a special file called **/​dev/​fb0**. This file is an abstraction of the [[https://​www.kernel.org/​doc/​html/​latest/​fb/​framebuffer.html|frame buffer]] used by your video hardware to render your screen. In it, each pixel is represented as a RGBA (Red-Green-Blue-Alpha) value. Creating a copy of this file to persistent storage will effectively take a screenshot. Unfortunately,​ this screenshot will not be in any known format (e.g.: JPEG, PNG, etc.) A bit of work still needs to be done to properly format it such that the appropriate software (e.g.**gwenview**) can interpret and display it. +Our customer wants to make some changes ​to the website'​s design:
  
-In this first exercise, we are going to write a //Python3// script that does just thattake the content ​of /dev/fb0 and output an image file in a format of your choosingTo that endwe are going to use the [[https://pillow.readthedocs.io/en/​stable/​index.html|PIL module]].+  * Add header image with our logo at the top 
 +      * Several candidates are present inside ''​public/images/'';​ 
 +      * You could either use the [[https://developer.mozilla.org/​en-US/​docs/​Web/​CSS/​background-image|CSS background property]], or just the old-school ''<​img>''​ tag; 
 +      * **Hint:** check out ''​style.css''​ for existing definitions! 
 +  * Also change ​the background color of the ''<​header>''​ to match the chosen ​image on its margins (maybe something blue?); 
 +  * Make the content box have rounded borders (try ''​15px''​);​ 
 +      * ''​border-radius''​ *wink* 
 +      * Use the browser'​s Web Developer tools to find the HTML tag to select! 
 +  * Insert some dummy content text (e.g., use [[https://loremipsum.io/|Lorem Ipsum generator]]);
  
-=== [??p] Task A - Setting up the environment ===+<note tip> 
 +Hint: search for TODOs inside HTML and CSS! 
 +</​note>​
  
-First of all, we are going to set up a virtual environment for us to work inIf you need a reminder on what a venv actually isrefer to [[https://ocw.cs.pub.ro/​courses/​ii/​labs/​03/​tasks/​01|this lab]].+<note important>​ 
 +For specifying URLs to other web resources (e.g., images for this task)recall Unix relative paths (''​./path/to/file.jpg''​)?​ 
 +HTML also uses them (those URLs will be relative to your current file -- either the ''​.html''​ or the ''​.css''​)!
  
-<code bash> +In some cases (webpage has sub-pathse.g., ''/​account/details.html''​),​ you may also use absolute URLs (path begins ​with a ''/'' ​representing ​the server'​s ​root directory). 
-# this will be our workspace directory +</note>
-$ mkdir frame_buffer +
-$ cd !$ +
- +
-# create venv and activate it +
-$ python3 -m venv .venv +
-$ source .venv/​bin/​activate +
- +
-# install pillow ​(an actively maintained fork of PIL) +
-$ pip3 install pillow +
-</​code>​ +
- +
-=== [??p] Task B Writing the script === +
- +
-To start things offwe are going to use the following skeleton: +
- +
-<file python fb2img.py> +
-#!.venv/​bin/​python3 +
- +
-import argparse ​        # argument parsing +
-import struct ​          # data unpacking +
-from PIL import Image   # image processing +
- +
-def main(): +
-    # parse cli arguments +
-    parser = argparse.ArgumentParser() +
-    parser.add_argument('​FILE'​help='output image file'+
-    parser.add_argument('​--src',​ help='​data source',​ +
-                        default='/​dev/​fb0',​ metavar='/​dev/​fb*'​) +
-    parser.add_argument('​--width',​ help='​screen width [px]',​ +
-                        type=int, default=1920,​ metavar='​ INT'​) +
-    parser.add_argument('​--height',​ help='​screen height [px]',​ +
-                        type=int, default=1080,​ metavar='​INT'​) +
-    cfg = parser.parse_args() +
- +
-    # TODO 1: read contents of cfg.src (the frame buffer) +
-     +
-    # TODO 2: split data in groups of 4 bytes +
-     +
-    # create a new PIL Image object +
-    img = Image.new('​RGB',​ (cfg.width, cfg.height)) +
-    px  = img.load() +
- +
-    # set each pixel value +
-    for i in range(cfg.width):​ +
-        for j in range(cfg.height):​ +
-            # TODO 3: write each pixel value in px[i,j] as a RGB tuple +
-            # NOTE  : the four bytes in the groups that you split previously +
-            #         are in fact in BGRA format; we don't need the Alpha +
-            #         value but the other three bytes must be revered +
-            pass +
- +
-    # save image do disk +
-    # NOTE: format will be determined from the file's extension +
-    img.save(cfg.FILE,​ None) +
- +
-    # clean up PIL Image object +
-    img.close() +
- +
-if __name__ == '​__main__':​ +
-    main() +
-</​file>​ +
- +
-The script uses the [[https://​docs.python.org/​3/library/argparse.html|argparse module]] to interpret some command-line arguments (the ''​%%--%%help''​ flag is implied). If you feel like adding something to these, you're free to do so. It's a good idea to make your script as interactive as possible. The parsed arguments ​(or their default values) are stored as members of the //cfg// object. If you're unsure how to access them, just print the whole object once to get a feel for what it contains. +
- +
-For now, go through each //TODO// in the skeleton and fill in the blanks. Next are a few hints that might help you. Feel free to ask for help if you get stuck :) +
- +
-== TODO 1 == +
-This step is pretty straightforward. Remember that you are working ​with a //binary// file! +
- +
-== TODO 2 == +
-The result from the previous step will be a //byte array//. In order to split it into an array of 4-byte RGBA sub-arrays, you can use **list comprehension** (discussed in [[https://​ocw.cs.pub.ro/​courses/​ii/​labs/​02|this lab]]. If you have other ideas, you're free to do your own thing. +
- +
-== TODO 3 == +
-While //img// is a PIL abstraction of the image you wish to create, individual pixels will be accessed via //px//, an instance of the [[https://​pillow.readthedocs.io/​en/​stable/​reference/​PixelAccess.html|PixelAccess]] class in PIL. Each pixel is represented as a tuple of three integers (i.e.: not bytes). To __unpack__ each value from the byte-array corresponding to your pixel, you can use the [[https://​docs.python.org/​3/​library/​struct.html|struct module]]. Search in the documentation for the format character representing an ''​unsigned char''​ (equivalent to ''​uint8_t''​). +
- +
-Remember that you don't have to get the script right from your first try. If you're not familiar with a module, experiment with it a bit in a **python** shell. Or better yet, use **ipython**. +
- +
-=== [??p] Task C - Testing the script === +
- +
-Finally, it'​s ​time to test the script. Notice how your script takes the ''​%%--%%width''​ and ''​%%--%%height''​ optional arguments (with values defaulting to 1920 and 1080). If you have another resolution but you're not sure what that is, it's not hard to find out: +
- +
-<code bash> +
-$ xrandr --prop | grep primary +
-    eDP-1 connected primary 1920x1080+0+0 (normal left inverted right x axis y axis) 344mm x 194mm +
-</code> +
- +
-Note that /dev/fb0 has restricted access permissions for non-owners, so you need to run your script with **sudo**: +
- +
-<code bash> +
-$ ls -l /dev/fb0 +
-    crw-rw---- 1 root video 29, 0 Apr 14 17:45 /dev/fb0 +
- +
-$ sudo ./fb2img.py screenshot.png +
-</​code>​ +
- +
-Now let's open the screenshot with the default application:​ +
- +
-<code bash> +
-$ xdg-open screenshot.png +
-</​code>​ +
- +
-The result may be a bit unexpected, depending on how your [[https://​www.x.org/​wiki/​|X display server]] is configured. We'll discuss that in the next exercise :)+
ii/labs/s2/02/tasks/01.1649956636.txt.gz · Last modified: 2022/04/14 20:17 by radu.mantu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0