Giveup Tech

Ejoin life, Just simple
Aug 28, 2013

经常切换 google dns 和 114 dns,就写了个脚本,放到个人~/bin目录下。

#!/bin/bash

if [ $# -ne 2 ] ; then
    echo Useage: $0 network dnsgroup
    exit 0
fi

network=$1
case $1 in
    e ) network=Ethernet ;;
    w ) network=Wi-Fi ;;
esac

dns=$2
case $2 in
    114 ) dns='114.114.114.114 114.114.115.115' ;;
    8 ) dns='8.8.8.8 8.8.4.4' ;;
esac

networksetup -setdnsservers $network $dns

需要将此代码保存为文件到~/bin/usedns,并加执行权限。然后运行

usedns e 114

即可切换有线网络的dns到 114 dns。

Sep 13, 2012

下面是cv::Mat转gdiplus::Bitmap的函数:

Gdiplus::Bitmap(rgbImage.cols, rgbImage.rows, rgbImage.step, 
    PixelFormat24bppRGB, (BYTE*)rgbImage.data)

图像从cv::Mat转gdiplus::Bitmap时某些图转化会出错,原因是行字节对齐问题。cv::Mat默认是行连续的,没有对齐每一行的字节,而gdiplus::Bitmap的每一行都是4字节对齐的,为方便32位系统处理提高性能,而且是强制要求。

通过cv::imread函数和cv系列的其他函数得到的图像都是非字节对齐的,只有某些特殊函数,比如从IplImage得到的函数才是4字节对齐的。这就造成列数非4的整数倍的图像无法直接转化到Bitmap。

解决方法我想出3种:

  • 在转化以前先对Mat对象进行resize,缩放到列为4的整数倍,避免问题;
  • 通过新建一块内存,再按照一定的方法把Mat中的每一行字节复制到新内存中,使用这块内存作为函数的BYTE*变量,第三个参数就不能使用rgbImage.step,需要对对齐字节数量进行调整;
  • 对原图clip,裁剪到列为4的整数倍;

目前我使用第一种方法,因为我用到的都是显示缩略图,不影响功能。第二种和第三种都涉及到拷贝内存问题,需要额外时间和空间。第三种找了半天没找到直接使用clip的函数,算了。

Sep 10, 2012

在使用vc++2010运行一个使用opencv的findContour函数时遇到错误,在stackoverflow上找到了相同的问题:

http://stackoverflow.com/questions/11677118/opencv-example-code-for-find-contours-vector-deallocation-issue

按照so上给出的答案,修改了当前程序的vc运行库配置,问题解决。具体方法是:项目-属性-配置属性-C/C++-代码生成-运行库,将其改为“多线程调试(/MTd)”。

Jul 18, 2012

安装Django应用发现图片上传老出问题,发现时默认pip安装的PIL没有链接libjpeg等库,导致不能支持JPEG图片。总结,安装完服务器应该安装的模块有

sudo apt-get install zlib1g-dev liblcms1-dev python-dev
sudo apt-get install libjpeg8 libjpeg8-dev libpng12-0 libpng12-dev libfreetype6 libfreetype6-dev zlib1g-dev

然后

sudo pip install PIL

或者直接

sudo apt-get install python-imaging

还发现如果通过pip安装MySQL-python需要安装一下模块

sudo apt-get install python-dev libmysqlclient-dev

本文测试环境为ubuntu server 12.04

Apr 3, 2012

打开Gmail,发现整个网页一片黑,所有的主题背景和图片、图标都不见了,研究了一下,是ssl.gstatic.com这个域名被强奸了,于是乎,咱们老办法:修改hosts文件,加入:

74.125.227.111 ssl.gstatic.com

刷新,亮了。

Apr 3, 2012

最近由于想要使用Dropbox的多人协作功能,就发现Dropbox不能自动同步其他机器上产生的文件变化,经过一番搜索,发现原来是GFW在作怪(GFW和GD的性质和用心我们心知肚明,就不在这里评价了)。月光博客发布了解决Dropbox无法实时更新的问题分析了产生这个问题的原因并提出一个有效的解决方案。但是在使用时我发现,我找不到一个优良稳定的代理服务器,也没工夫去学习privoxy软件的配置和使用,而且我要将解决方案提供给我的合伙人,一个复杂的方案是不能接受的。经过一番研究,提出如下比较简单的办法:

分析

我发现Dropbox向notify8发出的请求很简单,回应也很简单,一共有两种:

{"ret":"new"}
和
{"ret":"punt"}

分别表示云端有变化和无变化,然后客户端考虑去下载文件列表并同步。

经过一番痛苦的失败,我发现这个请求的其实是一个comet请求,服务器端并不马上回应,而是会挂起,如果有变化,则马上回应,如果一直没有变化,大约一分钟超时回应punt,然后客户端再连接服务器。在我分析Dropbox的过程中一直不解:为什么Dropbox的其他请求都是https,而只有这一个请求是http的。现在找到了答案:因为它是comet请求,长连接,而且连接频率非常高,如果使用https代价太大,而且影响效率。如果这个请求返回new,客户端就会使用https连接服务器端。

解决

由此提出一个完美的解决方案,不仅可以解决本机的问题,而且可以解决朋友的问题,只要让朋友修改hosts为我的ip地址:

  • 修改hosts将notify8对应的ip地址改为本机
  • 在本机建立一个http服务,代理notify8得到dropbox的返回值,再原封不动地返回给本机dropbox客户端

具体方法是使用tornado,进行一步http请求,这样只占用很少一部分系统资源。贴出代码。

代码

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
from tornado import httpclient


define("port", default=8888, help="run on the given port", type=int)


class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/subscribe", NotifyHandler),
            (r"/.*", HomeHandler),
        ]
        settings = dict(
            debug=True,
        )
        self.debug = True
        tornado.web.Application.__init__(self, handlers, **settings)


class HomeHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_header("Content-Type", "text/plain")
        self.write("Hello from Tornado!")


class NotifyHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        self.set_header("Content-Type", "text/plain")
        url = xxxxx #关键代码还是不贴出来了,人怕出名猪怕壮,要是大多数人会用了,估计这个方法死期不远矣!
        http_client = httpclient.AsyncHTTPClient()
        http_client.fetch(url, self.handle_response, request_timeout=100.0)

    def handle_response(self, response):
        if response.error:
            print "Can not connect."
            self.write("{\"ret\": \"new\"}")
        else:
            print "Connect Successfull."
            self.write(response.body)
        self.finish()


def main():
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(Application())
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    main()

版权声明:原创作品,允许转载,转载请务必以超链接形式标明原始出处,否则将追究法律责任。GiveupTech.com

Apr 2, 2012

Dropbox里面直接写博客,貌似很拉风的样子,呵呵,在此Mark一下,留个纪念。

以前写博客打一枪换一个地方,经常搬家不方便带走,好多文章就丢了,现在终于找到一个安全的地方,反正我的.md文件在,换个地方相当容易了。在此感谢Dropbox和Scriptogr.am提供的优良服务。