1.区域视频增强

FFmpeg滤镜功能十分强大,用滤镜可以实现视频的区域增强功能。

用eq滤镜就可以实现亮度、对比度、饱和度等的常用视频增强功能。

推荐两篇写得不错的博文:

(1)ffmpeg综合应用示例(二)——为直播流添加特效 - 张晖的专栏 - 博客频道 - CSDN.NET

(2)ffmpeg 滤镜及其效果 - 党玉涛 - 博客频道 - CSDN.NET

第(1)篇博客对于如何用代码来写滤镜讲得比较清楚,第(2)篇则列出了许多滤镜写法的例子。

参考第(1)篇博客,滤镜的代码如下:

设置滤镜:

int FFmpeg_filter::apply_filters(AVFormatContext *ifmt_ctx)
{
char args[];
int ret;
AVFilterInOut *outputs = avfilter_inout_alloc();
if (!outputs)
{
printf("Cannot alloc output\n");
return -;
}
AVFilterInOut *inputs = avfilter_inout_alloc();
if (!inputs)
{
printf("Cannot alloc input\n");
return -;
} AVFilterGraph *filter_graph = NULL;
if (filter_graph)
avfilter_graph_free(&filter_graph);
filter_graph = avfilter_graph_alloc();
if (!filter_graph)
{
printf("Cannot create filter graph\n");
return -;
} /* buffer video source: the decoded frames from the decoder will be inserted here. */
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
ifmt_ctx->streams[]->codec->width, ifmt_ctx->streams[]->codec->height, ifmt_ctx->streams[]->codec->pix_fmt,
ifmt_ctx->streams[]->time_base.num, ifmt_ctx->streams[]->time_base.den,
ifmt_ctx->streams[]->codec->sample_aspect_ratio.num, ifmt_ctx->streams[]->codec->sample_aspect_ratio.den); ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
args, NULL, filter_graph);
if (ret < ) {
printf("Cannot create buffer source\n");
return ret;
} /* buffer video sink: to terminate the filter chain. */
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
NULL, NULL, filter_graph);
if (ret < ) {
printf("Cannot create buffer sink\n");
return ret;
} /* Endpoints for the filter graph. */
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx = ;
outputs->next = NULL; inputs->name = av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx = ;
inputs->next = NULL; const char *filter_descr = "null";
const char *filter_mirror = "crop=iw/2:ih:0:0,split[left][tmp];[tmp]hflip[right];[left]pad=iw*2[a];[a][right]overlay=w";
const char *filter_watermark = "movie=logo.png[wm];[in][wm]overlay=5:5[out]";
const char *filter_negate = "negate[out]";
const char *filter_edge = "edgedetect[out]";
const char *filter_split4 = "scale=iw/2:ih/2[in_tmp];[in_tmp]split=4[in_1][in_2][in_3][in_4];[in_1]pad=iw*2:ih*2[a];[a][in_2]overlay=w[b];[b][in_3]overlay=0:h[d];[d][in_4]overlay=w:h[out]";
const char *filter_vintage = "curves=vintage";
const char *filter_brightness = "eq=brightness=0.5[out] "; //亮度。The value must be a float value in range -1.0 to 1.0. The default value is "0".
const char *filter_contrast = "eq=contrast=1.5[out] "; //对比度。The value must be a float value in range -2.0 to 2.0. The default value is "1".
const char *filter_saturation = "eq=saturation=1.5[out] "; //饱和度。The value must be a float in range 0.0 to 3.0. The default value is "1".
//const char *filter_eq = "eq=contrast=1.0:brightness=-0.0:saturation=1.0 ";
char filter_eq[];
float t_brightness_value = _brightness_value ;
float t_contrast_value = _contrast_value ;
float t_saturation_value = _saturation_value ;
snprintf(filter_eq, sizeof(filter_eq), "eq=brightness=%f:contrast=%f:saturation=%f", t_brightness_value, t_contrast_value, t_saturation_value);
printf("eq=brightness=%f:contrast=%f:saturation=%f \n", t_brightness_value, t_contrast_value, t_saturation_value); int x = ;
int y = ;
int iWidth = ;
int iHeight = ;
char filter_test[];
snprintf(filter_test, sizeof(filter_test), "[in]split[ori][tmp];[tmp]crop=%d:%d:%d:%d,eq=brightness=%f:contrast=%f:saturation=%f[eq_enhance];[ori][eq_enhance]overlay=%d:%d[out]",
iWidth, iHeight, x, y, t_brightness_value, t_contrast_value, t_saturation_value, x, y); switch(_filter)
{
case FILTER_NULL:
filter_descr = "null";
break;
case FILTER_MIRROR:
filter_descr = filter_mirror;
break;
case FILTER_WATERMARK:
filter_descr = filter_watermark;
break;
case FILTER_NEGATE:
filter_descr = filter_negate;
break;
case FILTER_EDGE:
filter_descr = filter_edge;
break;
case FILTER_SPLIT4:
filter_descr = filter_split4;
break;
case FILTER_VINTAGE:
filter_descr = filter_vintage;
break;
case FILTER_BRIGHTNESS:
filter_descr = filter_brightness;
break;
case FILTER_CONTRAST:
filter_descr = filter_contrast;
break;
case FILTER_SATURATION:
filter_descr = filter_saturation;
break;
case FILTER_EQ:
filter_descr = filter_eq;
break;
case FILTER_TEST:
filter_descr = filter_test;
break;
default:
break;
} if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_descr,
&inputs, &outputs, NULL)) < )
return ret; if ((ret = avfilter_graph_config(filter_graph, NULL)) < )
return ret; avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs); return ;
}

应用滤镜:

while (av_read_frame(pFormatCtx, packet) >= ){
EnterCriticalSection(&cs) ;
if (packet->stream_index == videoindex){
ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if (ret < ){
printf("Decode Error.\n");
return -;
}
if (got_picture){ pFrame->pts = av_frame_get_best_effort_timestamp(pFrame); if (filter_change)
apply_filters(pFormatCtx);
filter_change = ;
/* push the decoded frame into the filtergraph */
if (av_buffersrc_add_frame(buffersrc_ctx, pFrame) < ) {
printf("Error while feeding the filtergraph\n");
break;
}
picref = av_frame_alloc(); while () {
ret = av_buffersink_get_frame_flags(buffersink_ctx, picref, );
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < )
return ret; if (picref) {
img_convert_ctx = sws_getContext(picref->width, picref->height, (AVPixelFormat)picref->format, pCodecCtx->width, pCodecCtx->height, target_format, SWS_BICUBIC, NULL, NULL, NULL);
sws_scale(img_convert_ctx, (const uint8_t* const*)picref->data, picref->linesize, , pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize); _d3d_video_render.Render_Texture(pFrameYUV->data[],picref->width,picref->height) ; sws_freeContext(img_convert_ctx); }
av_frame_unref(picref);
} SDL_Delay();
}
}
av_free_packet(packet); LeaveCriticalSection(&cs) ;
}

apply_filters函数修改滤镜的设置。另外有两个比较重要的函数:av_buffersrc_add_frame函数和av_buffersink_get_frame_flags函数。至于区域增强,其实主要就是如下代码:

snprintf(filter_test, sizeof(filter_test), "[in]split[ori][tmp];[tmp]crop=%d:%d:%d:%d,eq=brightness=%f:contrast=%f:saturation=%f[eq_enhance];[ori][eq_enhance]overlay=%d:%d[out]",
iWidth, iHeight, x, y, t_brightness_value, t_contrast_value, t_saturation_value, x, y);

含义就是把输入流分成ori和tmp,把tmp从像素坐标(x,y)开始,以iWidth为宽,以iHeight为高的部分crop出来,使用eq滤镜后再叠加到ori对应位置。

2.D3D实现视频播放区的拉大缩小

用D3D的纹理可以做出许多非常有意思的效果。使用纹理可以做各种变换轻松实现视频播放区的拉大缩小,视频旋转也可以非常轻松的实现,我没有做,不过只需要修改一下相机的向上方向就可以轻松实现90°的旋转,但要实现任意角度,则还需要稍作计算,我没有做,就不多说了。

初始化D3D:

BOOL CD3DVidRender::InitD3D_Texure(HWND hwnd, int img_width, int img_height, RENDER_DATA_TYPE data_type)
{
if (!hwnd)
{
return false ;
} D3DDEVTYPE deviceType = D3DDEVTYPE_HAL ;
bool windowed = true ; HRESULT hr = ; // Step 1: Create the IDirect3D9 object. IDirect3D9* d3d9 = ;
d3d9 = Direct3DCreate9(D3D_SDK_VERSION); if( !d3d9 )
{
::MessageBox(, "Direct3DCreate9() - FAILED", , );
return false;
} // Step 2: Check for hardware vp.
D3DCAPS9 caps;
d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps); int vp = ;
if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; // Step 3: Fill out the D3DPRESENT_PARAMETERS structure.
D3DDISPLAYMODE d3ddm;
UINT adapter = D3DADAPTER_DEFAULT;
IDirect3D9_GetAdapterDisplayMode(d3d9, adapter, &d3ddm); D3DPRESENT_PARAMETERS d3dpp;
// 默认不使用多采样
D3DMULTISAMPLE_TYPE multiType = D3DMULTISAMPLE_NONE;
if(d3d9->CheckDeviceMultiSampleType(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, D3DFMT_A8R8G8B8, !windowed,
D3DMULTISAMPLE_4_SAMPLES,
NULL) == D3D_OK)
{
multiType = D3DMULTISAMPLE_4_SAMPLES;
} d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferWidth = img_width;
d3dpp.BackBufferHeight = img_height;
d3dpp.BackBufferCount = ;
d3dpp.MultiSampleType = multiType;
d3dpp.MultiSampleQuality = ;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.Windowed = windowed;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
d3dpp.Flags = ;
d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Step 4: Create the device.
hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT, // primary adapter
deviceType, // device type
hwnd, // window associated with device
vp, // vertex processing
&d3dpp, // present parameters
&m_pDirect3DDevice); // return created device if( FAILED(hr) )
{
// try again using a 16-bit depth buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16; hr = d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
deviceType,
hwnd,
vp,
&d3dpp,
&m_pDirect3DDevice); if( FAILED(hr) )
{
d3d9->Release(); // done with d3d9 object
::MessageBox(, "CreateDevice() - FAILED", , );
return false;
}
} d3d9->Release(); // done with d3d9 object _data_type = data_type ;
m_Hwnd = hwnd ; if (!Setup_Texture(hwnd,m_pDirect3DDevice,img_width,img_height,data_type))
{
return false ;
} return TRUE;
}

设置纹理:

BOOL CD3DVidRender::Setup_Texture(HWND hwnd,IDirect3DDevice9* Device, int Width, int Height, RENDER_DATA_TYPE data_type)
{
if (!Device)
{
return false ;
}
Device = m_pDirect3DDevice ; HRESULT hr = ; float x_w = Width / ;
float y_h = Height / ; hr = Device->CreateVertexBuffer(
* sizeof(MultiTexVertex),
D3DUSAGE_WRITEONLY,
MultiTexVertex::FVF,
D3DPOOL_MANAGED,
&QuadVB,
); MultiTexVertex* v = ;
QuadVB->Lock(, , (void**)&v, );
v[] = MultiTexVertex(-20.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[] = MultiTexVertex( 20.0f, 20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
v[] = MultiTexVertex( 20.0f, -20.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
v[] = MultiTexVertex(-20.0f, -20.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
QuadVB->Unlock(); RECT rc ;
GetClientRect(hwnd,&rc) ;
float v_z = (float)Width / (float)rc.right ; D3DXMATRIX P;
D3DXMatrixPerspectiveFovLH(&P,
D3DX_PI * 0.5f,
1.0f,
1.0f, //近裁减面到坐标原点的距离
1000.0f //远裁减面到原点的距离
);
Device->SetTransform(D3DTS_PROJECTION, &P);
Device->SetRenderState(D3DRS_LIGHTING, false); m_RadiusFirst = m_Radius = ;
m_AngleFirst = m_Angle = (3.0f * D3DX_PI) / 2.0f; D3DXVECTOR3 position( x_Cam, y_Cam, sinf(m_Angle) * m_Radius);
D3DXVECTOR3 target(x_Cam, y_Cam, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V, &position, &target, &up);//计算取景变换矩阵
m_pDirect3DDevice->SetTransform(D3DTS_VIEW, &V);//取景变换 if(data_type == RENDER_DATA_TYPE_YUV420P)
{
ID3DXBuffer* shader = ;
ID3DXBuffer* errorBuffer = ; hr = D3DXCompileShaderFromFile(
"E:\\workspace\\Shader\\SDKTexShaderDemo\\SDKTexShaderDemo\\ps_yuv420p.txt",
,
,
"Main", // entry point function name
"ps_2_0",
D3DXSHADER_DEBUG,
&shader,
&errorBuffer,
&MultiTexCT); if( errorBuffer )
{
::MessageBox(, (char*)errorBuffer->GetBufferPointer(), , );
errorBuffer->Release() ;
} if(FAILED(hr))
{
::MessageBox(, "D3DXCompileShaderFromFile() - FAILED", , );
return false;
} hr = Device->CreatePixelShader((DWORD*)shader->GetBufferPointer(), &MultiTexPS);
if(FAILED(hr))
{
::MessageBox(, "CreateVertexShader - FAILED", , );
return false;
} if (shader)
{
shader->Release() ;
} Device->CreateTexture ( Width, Height, , D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &YTex, NULL ) ;
Device->CreateTexture ( Width / , Height / , , D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &UTex, NULL ) ;
Device->CreateTexture ( Width / , Height / , , D3DUSAGE_DYNAMIC, D3DFMT_L8, D3DPOOL_DEFAULT, &VTex, NULL ) ; D3DXHANDLE YTexHandle = MultiTexCT->GetConstantByName(, "YTex");
D3DXHANDLE UTexHandle = MultiTexCT->GetConstantByName(, "UTex");
D3DXHANDLE VTexHandle = MultiTexCT->GetConstantByName(, "VTex"); UINT count; MultiTexCT->GetConstantDesc(YTexHandle, &YTexDesc, &count);
MultiTexCT->GetConstantDesc(UTexHandle, &UTexDesc, &count);
MultiTexCT->GetConstantDesc(VTexHandle, &VTexDesc, &count); MultiTexCT->SetDefaults(Device);
}
else
{
Device->CreateTexture ( Width, Height, , D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &YTex, NULL ) ;
} return true;
}

以上代码中,投影变换部分需要做一点说明,

MultiTexVertex* v = ;
QuadVB->Lock(, , (void**)&v, );
v[] = MultiTexVertex(-20.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
v[] = MultiTexVertex( 20.0f, 20.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);
v[] = MultiTexVertex( 20.0f, -20.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f);
v[] = MultiTexVertex(-20.0f, -20.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
QuadVB->Unlock(); RECT rc ;
GetClientRect(hwnd,&rc) ;
float v_z = (float)Width / (float)rc.right ; D3DXMATRIX P;
D3DXMatrixPerspectiveFovLH(&P,
D3DX_PI * 0.5f,
1.0f,
1.0f, //近裁减面到坐标原点的距离
1000.0f //远裁减面到原点的距离
);
Device->SetTransform(D3DTS_PROJECTION, &P);

我把纹理坐标设成了宽慰40(20X2)、位于z=0处的正方形,把D3DXMatrixPerspectiveFovLH的第3个参数设为了1,这样可以图像就会与hwnd指向的窗口保持统一宽高比,事实上应该是可以通过调整参数使得图像按自身的比例置于窗口的中间位置的,但我看了很多网上的博文,做了许多尝试都没有达到理想的效果,如果有能实现的,还请指教。另外,我把D3DXMatrixPerspectiveFovLH的第2个参数设为90°(D3DX_PI * 0.5f),这样就可以知道当相机与纹理的距离为20的时候,图像刚好完整填充窗口。这一块若有疑问,建议最好参考一下网上的资料。

接下来要做电子放大的效果就很容易了,只需要修改相机与纹理的距离,做取景变换就可以轻松实现电子放大的拉大缩小效果,代码如下:

void CD3DVidRender::ZoomIn()
{
m_Radius += m_RadiusFirst / 25.0f; if (m_Radius >= )
{
m_Radius = ;
} D3DXVECTOR3 position( -x_curCam, y_curCam, sinf(m_Angle) * m_Radius);
D3DXVECTOR3 target(-x_curCam, y_curCam, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V, &position, &target, &up);//计算取景变换矩阵 m_pDirect3DDevice->SetTransform(D3DTS_VIEW, &V);//取景变换
} void CD3DVidRender::ZoomOut()
{
m_Radius -= m_RadiusFirst / 20.0f; if (m_Radius <= 1.1f)
{
m_Radius = 1.1f ;
} D3DXVECTOR3 position( -x_curCam, y_curCam, sinf(m_Angle) * m_Radius);
D3DXVECTOR3 target(-x_curCam, y_curCam, 0.0f);
D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
D3DXMATRIX V;
D3DXMatrixLookAtLH(&V, &position, &target, &up);//计算取景变换矩阵 m_pDirect3DDevice->SetTransform(D3DTS_VIEW, &V);//取景变换
}

完整工程代码:http://download.csdn.net/download/qq_33892166/9725905

FFmpeg滤镜实现区域视频增强 及 D3D实现视频播放区的拉大缩小的更多相关文章

  1. 利用FFmpeg玩转Android视频录制与压缩(二)<转>

    转载出处:http://blog.csdn.net/mabeijianxi/article/details/72983362 预热 时光荏苒,光阴如梭,离上一次吹牛逼已经过去了两三个月,身边很多人的女 ...

  2. FFmpeg滤镜使用

    滤镜(filter)详细介绍参考官方文档. 常用的滤镜功能,像图像加水印/字幕.去logo.图形旋转缩放等,但滤镜不仅仅包括视频部分,还包括音频处理的,像变声变调.声场控制(重低音/留声机/摇滚等效果 ...

  3. FFmpeg滤镜使用指南

    文件夹 1. FFmpeg滤镜文档 2. 演示样例   2.1 缩放   2.2 视频加速   2.3 滤镜图,链和滤镜关系   2.4 多个输入覆盖同一个2x2 网格   2.5 转义字符   2. ...

  4. ffmpeg 安装,转视频格式为m3u8,压缩视频

    # ffmpegffmpeg 安装,转视频格式为m3u8,压缩视频 ## ffmpeg 安装直接安装: apt-get install ffmpeg 运行 `ffmpeg` 看是否出现版本号以判断是否 ...

  5. [开源]基于ffmpeg和libvlc的视频剪辑、播放器

    [开源]基于ffmpeg和libvlc的视频剪辑.播放器 以前研究的时候,写过一个简单的基于VLC的视频播放器.后来因为各种项目,有时为了方便测试,等各种原因,陆续加了一些功能,现在集成了视频播放.视 ...

  6. FFmpeg 入门(5):视频同步

    本文转自:FFmpeg 入门(5):视频同步 | www.samirchen.com 视频如何同步 在之前的教程中,我们已经可以开始播放视频了,也已经可以开始播放音频了,但是视频和音频的播放还未同步, ...

  7. FFmpeg滤镜代码级分析

    http://blog.chinaunix.net/uid-26000296-id-3322071.html 前一篇文章<为FFmpeg添加自定义滤镜>详细讲述了FFmpeg的滤镜添加步骤 ...

  8. 基于ffmpeg和libvlc的视频剪辑、播放器

    以前研究的时候,写过一个简单的基于VLC的视频播放器.后来因为各种项目,有时为了方便测试,等各种原因,陆续加了一些功能,现在集成了视频播放.视频加减速.视频剪切,视频合并(增加中)等功能在一起.有时候 ...

  9. 交叉编译多平台 FFmpeg 库并提取视频帧

    原文地址: 交叉编译多平台 FFmpeg 库并提取视频帧 交叉编译多平台 FFmpeg 库并提取视频帧 本文档适用于 x86 平台编译 armeabi.armeabi-v7a.arm64-v8a.x8 ...

随机推荐

  1. kali linux下的arp攻击

    这是我第一篇博客,写的不好请谅解 ____________________________(分割线)_______________________________ 在kali linux系统下自带工具 ...

  2. Visual Studio Code——Angular2 Hello World 之 2.0

    最近看到一篇用Visual Studio Code开发Angular2的文章,也是一篇入门教程,地址为:使用Visual Studio Code開發Angular 2專案.这里按部就班的做了一遍,感觉 ...

  3. Android 开发一定要看的15个实战项目

    前言: 虽说网上有太多的Android课程,但是大多都是视频,有Android在线开发环境的几乎没有,但是对于学习Android的人来说拥有在线的Android开发环境是非常好的,可以随时动手操作学习 ...

  4. 跨域问题,前端主动向后台发送cookie

    跨域是什么? 从一个域名的网页访问另一个域名的资源,就会出现跨域.只要协议.端口.域名有一个不同就会出现跨域 例如: 1.协议不同  http://www.baidu.com:80 和 https:/ ...

  5. AWS的SysOps认证考试样题解析

    刚考过了AWS的developer认证,顺手做了一下SysOps的样题.以下是题目和答案. When working with Amazon RDS, by default AWS is respon ...

  6. SQL Server 服务器磁盘测试之SQLIO篇(一)

    数据库调优工作中,有一部分是需要排查IO问题的,例如IO的速度或者RAID级别无法响应高并发下的快速请求.最常见的就是查看磁盘每次读写的响应速度,通过性能计数器Avg.Disk sec/Read(Wr ...

  7. struts debug 标签

    < s:debug> 引起下面的错误 org.apache.jasper.JasperException: Caught an exception while getting the pr ...

  8. Atitit. 破解  拦截 绕过 网站 手机 短信 验证码  方式 v2 attilax 总结

    Atitit. 破解  拦截 绕过 网站 手机 短信 验证码  方式 v2 attilax 总结 1. 验证码的前世今生11.1. 第一代验证码 图片验证码11.2. 第二代验证码  用户操作 ,比如 ...

  9. windows下获取IP地址的两种方法

    windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...

  10. 在PC上测试移动端网站和模拟手机浏览器的5大方

    查了很多资料,尝试了大部分方法,下面将这一天的努力总结下分享给大家,也让大家免去看那么多文章,以下介绍的方法,都是本人亲自测试成功的方法,测试环境winxp. 一.Chrome*浏览器 chrome模 ...