Arduino论坛
直播中

余华

11年用户 427经验值
擅长:可编程逻辑 嵌入式技术 处理器/DSP
私信 关注
[资料]

enc28J60 和 Arduino (8)——Arduino处理图片

我发表上一篇教程如何使用网页控制Led后,有人问我如何控制一个以上的Led,今天我来告诉你如何控制两个Led,并用更为时尚的网页元素—图像。

图像
    首先你要明白当一个网页引用了一些外部资源(如图像,javascript...)后的处理流程:
  • 用户的浏览器连接web服务器,请求HTML网页。
  • 浏览器解析页面,找到外部资源。
  • 浏览器向服务器请求每一个外部资源。

    当服务器应答,它在响应的头文件中告诉浏览器他发送的文件MIME类型。下面这个例子(用Fiddler嗅探)是关于PNG图像。

    Arduino代码应该能够:
  • 读取浏览器的请求(保存在Ethernet:buffer)。
  • 识别浏览器请求的资源(HTML页面、图像...)。
  • 创建一个正确的头文件(含类型Content-Type)。
  • 发送头文件和请求的资源到浏览器。


二进制资源
    图片是一个二进制文件,在这个例子中我们应该能够把它以字节数组(byte arrays)的形式存放在我们的代码中。我发现
bin2h这个工具可以帮助我们进行转换。
    转换结果是一个文本文件:

    为了节省Arduino内存,我们用PROGMEM指令存储在flash中:


Arduino
    同往常一样,完整的代码共享在GitHub
    下面是我的代码将显示在浏览器的网页。

    当用户点击其中一个图标,浏览器将请求该页面并添加?LEDx后缀:Arduino将改变相应的Led状态和图标的颜色。

    让我们先来了解一些代码片段。
  •     if(strstr((char *)Ethernet::buffer + pos, "GET /led_off.png") != 0)
  •       send_png_image(led_off, sizeof(led_off));
  •     else if(strstr((char *)Ethernet::buffer + pos, "GET /led_on.png") != 0)
  •       send_png_image(led_on, sizeof(led_on));

[color=rgb(51, 102, 153) !important]复制代码

我们的代码解析浏览器的请求,如果请求两个图片中的一个图片,调用send_png_image()方法,把它发送给浏览器。
  • void send_png_image(PGM_P png_image, unsigned int image_size) {
  •   BufferFiller bfill = ether.tcpOffset();
  •   bfill.emit_p(PSTR("HTTP/1.0 200 OKrn"
  •     "Content-Type: image/pngrnrn"));
  •   bfill.emit_raw_p(png_image, image_size);
  •   ether.httpServerReply(bfill.position());
  • }

[color=rgb(51, 102, 153) !important]复制代码

这个方法准备正确头文件及用emit_raw_p方法添加图形文件的二进制数据到响应,最后用httpServerReply()发送响应给浏览器。
  • if(strstr((char *)Ethernet::buffer + pos, "GET /?LED1") != 0) {
  •   led1Status = !led1Status;
  •   digitalWrite(LED1PIN, led1Status);
  • }

[color=rgb(51, 102, 153) !important]复制代码

如果浏览器的请求中包含?LEDx,Led的状态发生改变,HTML页面重新创建,根据Led的状态设定正确的图标。


回帖(1)

mkxjs

2015-1-9 16:48:54
看不懂啊,什么东西啊》
举报

更多回帖

发帖
×
20
完善资料,
赚取积分