鱼C论坛

 找回密码
 立即注册
楼主: 额外减小

[作品展示] 看烟花

[复制链接]
 楼主| 发表于 2023-1-30 21:16:52 | 显示全部楼层
Mike_python小 发表于 2023-1-30 21:14
卧槽原来可以不用windows.h,我这就去试试

只要你可以找到跟sleep()函数对应的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-30 21:19:21 | 显示全部楼层
额外减小 发表于 2023-1-30 21:16
只要你可以找到跟sleep()函数对应的

这就抛弃clion,去投奔xcode(不过太大了)

评分

参与人数 1荣誉 +1 收起 理由
额外减小 + 1 我被吞帖了,稍等

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 21:21:31 | 显示全部楼层
Mike_python小 发表于 2023-1-30 21:19
这就抛弃clion,去投奔xcode(不过太大了)

不是
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 21:22:39 | 显示全部楼层
Mike_python小 发表于 2023-1-30 21:19
这就抛弃clion,去投奔xcode(不过太大了)

你听我说
确实要加windows.h
跟编译器没什么关系。
不是她的错()

你要不去其他库里面找对应的函数?
或者自己写一个()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 21:24:08 | 显示全部楼层
Mike_python小 发表于 2023-1-30 21:19
这就抛弃clion,去投奔xcode(不过太大了)

跟编译器没有关系

实际上要加windows.h
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-30 23:15:31 | 显示全部楼层

回帖奖励 +1 鱼币

不管是你创建的窗口也好,还是现有的窗口也好,只要知道了id,那么画吧,想画什么就画什么
是的,你没有看错,这是在那个黑框框里面画的,用gdi函数给这个黑框框贴了一个图片,^_^
那么任务来了,把前言中的那个图片效果做出来,当然不是要你贴一个图片上去,是要动画效果,^_^
贴图片的代码我给你了,不停的贴图片就是动画
#include <stdio.h>
#include <windows.h>

int main(void) {
    HWND hwnd = GetConsoleWindow();
    HDC hdc_cmd = GetDC(hwnd);
    HBITMAP img = LoadImage(NULL, "image.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
    HDC hdc_img = CreateCompatibleDC(NULL);
    HGDIOBJ obj_hdc = SelectObject(hdc_img, img);
    BITMAP bm; GetObject(img, sizeof(BITMAP), &bm);
    BitBlt(hdc_cmd, 0, 0, bm.bmWidth, bm.bmHeight, hdc_img, 0, 0, SRCCOPY);
    SelectObject(hdc_img, obj_hdc);
    DeleteDC(hdc_img);
    DeleteObject(img);
    ReleaseDC(hwnd, hdc_cmd);
    getchar();
    return 0;
}

1.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-30 23:27:56 | 显示全部楼层
^_^
2.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 23:31:01 | 显示全部楼层
人造人 发表于 2023-1-30 23:15
不管是你创建的窗口也好,还是现有的窗口也好,只要知道了id,那么画吧,想画什么就画什么
是的,你没有看 ...

!!!
膜拜大佬
但我不会”windows程序设计“
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 23:32:42 | 显示全部楼层
人造人 发表于 2023-1-30 23:15
不管是你创建的窗口也好,还是现有的窗口也好,只要知道了id,那么画吧,想画什么就画什么
是的,你没有看 ...

我没学到那么深

让我先去了解下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 23:37:17 | 显示全部楼层


报错了
虽然看不懂
但我想知道为什么
C:\Users\summer\Desktop\codehome>gcc cccc.c
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0x6e): undefined reference to `__imp_CreateCompatibleDC'
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0x86): undefined reference to `__imp_SelectObject'
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0xa6): undefined reference to `__imp_GetObjectA'
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0xf0): undefined reference to `__imp_BitBlt'
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0x104): undefined reference to `__imp_SelectObject'
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0x114): undefined reference to `__imp_DeleteDC'
C:\Users\summer\AppData\Local\Temp\ccEK7Upj.o:cccc.c:(.text+0x124): undefined reference to `__imp_DeleteObject'
collect2.exe: error: ld returned 1 exit status
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-30 23:37:58 | 显示全部楼层
额外减小 发表于 2023-1-30 23:37
报错了
虽然看不懂
但我想知道为什么

加上 -lgdi32
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-30 23:39:23 | 显示全部楼层
3.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-30 23:45:26 | 显示全部楼层
本帖最后由 额外减小 于 2023-1-30 23:46 编辑


QQ截图20230130234439.png

怎么回事呢
好像没有填满。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-31 00:00:43 | 显示全部楼层
额外减小 发表于 2023-1-30 23:45
怎么回事呢
好像没有填满。

我并没有对图片进行变换,图片是多大,贴上去就是多大
原样贴上去而已
^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-1-31 00:17:43 | 显示全部楼层
人造人 发表于 2023-1-31 00:00
我并没有对图片进行变换,图片是多大,贴上去就是多大
原样贴上去而已
^_^

好的。
那我试试看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-1 18:06:04 | 显示全部楼层
我又来了,这一次不贴图片了,贴视频,^_^
使用了ffmpeg这个库,目前只实现了视频,音频部分的代码还没写
要实现烟花动画,那就找一个烟花的视频
另外,有屏幕的地方就有BadApple对吧,^_^
怎么做呢?简单,把BadApple.mp4改成test.mp4,然后放到这个exe文件所在的目录,运行这个exe就可以了
论坛限制,发不了gif动画效果,那就贴几个图片吧

【视频素材】顶级烟花视频素材包无版权无水印[1080p HD]:https://www.bilibili.com/video/B ... 7311a641effed03ee60
#include <stdio.h>
#include <windows.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libswscale/swscale.h>
#include <libavutil/time.h>

#define SCREEN_WIDTH 1860
#define SCREEN_HEIGHT 930

void output_audio_frame(const AVFrame *frame) {
}

void write_frame(const AVFrame *frame) {
    HBITMAP img = CreateBitmap(frame->width, frame->height, 1, 32, frame->data[0]);
    HWND hwnd = GetConsoleWindow();
    HDC hdc_cmd = GetDC(hwnd);
    HDC hdc_img = CreateCompatibleDC(NULL);
    HGDIOBJ obj_hdc = SelectObject(hdc_img, img);
    BITMAP bm; GetObject(img, sizeof(BITMAP), &bm);
    BitBlt(hdc_cmd, 0, 0, bm.bmWidth, bm.bmHeight, hdc_img, 0, 0, SRCCOPY);
    SelectObject(hdc_img, obj_hdc);
    DeleteDC(hdc_img);
    ReleaseDC(hwnd, hdc_cmd);
    DeleteObject(img);
}

void output_video_frame(const AVFrame *frame) {
    int width = frame->width;
    int height = frame->height;
    struct SwsContext *sws_ctx = sws_getContext(width, height, frame->format, SCREEN_WIDTH, SCREEN_HEIGHT, \
            AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, NULL, NULL, NULL);
    AVFrame *frame_bgra = av_frame_alloc();
    frame_bgra->format = AV_PIX_FMT_BGRA;
    frame_bgra->width = SCREEN_WIDTH;
    frame_bgra->height = SCREEN_HEIGHT;
    av_frame_get_buffer(frame_bgra, 4);
    sws_scale(sws_ctx, (const uint8_t *const *)frame->data, frame->linesize, 0, height, frame_bgra->data, \
            frame_bgra->linesize);
    write_frame(frame_bgra);
    av_frame_free(&frame_bgra);
    sws_freeContext(sws_ctx);
}

void decode_packet(AVCodecContext *dec_ctx, const AVPacket *packet) {
    avcodec_send_packet(dec_ctx, packet);
    AVFrame *frame = av_frame_alloc();
    while(!avcodec_receive_frame(dec_ctx, frame)) {
        if(dec_ctx->codec->type == AVMEDIA_TYPE_AUDIO) output_audio_frame(frame);
        if(dec_ctx->codec->type == AVMEDIA_TYPE_VIDEO) output_video_frame(frame);
        av_frame_unref(frame);
    }
    av_frame_free(&frame);
}

int main(void) {
    const char *filename = "test.mp4";
    AVFormatContext *fmt_ctx = NULL;
    avformat_open_input(&fmt_ctx, filename, NULL, NULL);
    avformat_find_stream_info(fmt_ctx, NULL);
    av_dump_format(fmt_ctx, 0, filename, 0);
    int audio_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    int video_stream_idx = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
    AVStream *audio_stream = fmt_ctx->streams[audio_stream_idx];
    AVStream *video_stream = fmt_ctx->streams[video_stream_idx];
    const AVCodec *audio_dec = avcodec_find_decoder(audio_stream->codecpar->codec_id);
    const AVCodec *video_dec = avcodec_find_decoder(video_stream->codecpar->codec_id);
    AVCodecContext *audio_dec_ctx = avcodec_alloc_context3(audio_dec);
    AVCodecContext *video_dec_ctx = avcodec_alloc_context3(video_dec);
    avcodec_parameters_to_context(audio_dec_ctx, audio_stream->codecpar);
    avcodec_parameters_to_context(video_dec_ctx, video_stream->codecpar);
    avcodec_open2(audio_dec_ctx, audio_dec, NULL);
    avcodec_open2(video_dec_ctx, video_dec, NULL);
    AVPacket *packet = av_packet_alloc();
    int64_t start_time = av_gettime();
    while(!av_read_frame(fmt_ctx, packet)) {
        AVCodecContext *dec_ctx = NULL;
        int stream_idx = packet->stream_index;
        dec_ctx = stream_idx == audio_stream_idx ? audio_dec_ctx : dec_ctx;
        dec_ctx = stream_idx == video_stream_idx ? video_dec_ctx : dec_ctx;
        if(dec_ctx) decode_packet(dec_ctx, packet);
        int64_t pts = av_rescale_q(packet->pts, fmt_ctx->streams[stream_idx]->time_base, \
                av_make_q(1, AV_TIME_BASE));
        int64_t now_time = av_gettime() - start_time;
        if(pts > now_time) av_usleep(pts - now_time);
        av_packet_unref(packet);
    }
    decode_packet(audio_dec_ctx, NULL);
    decode_packet(video_dec_ctx, NULL);
    av_packet_free(&packet);
    avcodec_free_context(&video_dec_ctx);
    avcodec_free_context(&audio_dec_ctx);
    avformat_close_input(&fmt_ctx);
    return 0;
}

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg
7.jpg
8.jpg
9.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-1 19:03:55 | 显示全部楼层
人造人 发表于 2023-2-1 18:06
我又来了,这一次不贴图片了,贴视频,^_^
使用了ffmpeg这个库,目前只实现了视频,音频部分的代码还没写
...


没文化的我只能哇

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-2-1 19:04:28 | 显示全部楼层
人造人 发表于 2023-2-1 18:06
我又来了,这一次不贴图片了,贴视频,^_^
使用了ffmpeg这个库,目前只实现了视频,音频部分的代码还没写
...

您懂的真多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-1 19:09:36 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-2-3 19:53:14 | 显示全部楼层
继续,音频部分也没问题了
接下来就是合并这两个程序了
#include <stdio.h>
#include <initguid.h>
#include <windows.h>
#include <objbase.h>
#include <mmdeviceapi.h>
#include <audioclient.h>

void LoadData(BYTE *pData, UINT32 numBufferFrames, const WAVEFORMATEX *pwfx, DWORD *dwFlags) {
    UINT32 count = numBufferFrames * pwfx->nBlockAlign;
    size_t ret = fread(pData, 1, count, stdin);
    if(ret != count) {
        *dwFlags |= AUDCLNT_BUFFERFLAGS_SILENT;
        memset(pData + ret, 0, count - ret);
    }
}

int main(void) {
    freopen("test.pcm", "rb", stdin);
    CoInitialize(NULL);
    IMMDeviceEnumerator *pEnumerator;
    CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, \
            (LPVOID *)&pEnumerator);
    IMMDevice *pDevice;
    pEnumerator->lpVtbl->GetDefaultAudioEndpoint(pEnumerator, eRender, eMultimedia, &pDevice);
    IAudioClient *pAudioClient;
    pDevice->lpVtbl->Activate(pDevice, &IID_IAudioClient, CLSCTX_INPROC_SERVER, NULL, (LPVOID *)&pAudioClient);
    WAVEFORMATEX wfx = {
        .wFormatTag = WAVE_FORMAT_PCM,
        .nChannels = 2,
        .nSamplesPerSec = 44100,
        .nAvgBytesPerSec = 44100 * 8,
        .nBlockAlign = 8,
        .wBitsPerSample = 32,
        .cbSize = 0
    };
    WAVEFORMATEX *pwfx;
    pAudioClient->lpVtbl->IsFormatSupported(pAudioClient, AUDCLNT_SHAREMODE_SHARED, &wfx, &pwfx);
    if(!pwfx) {pwfx = CoTaskMemAlloc(sizeof(wfx)); *pwfx = wfx;}
    pAudioClient->lpVtbl->Initialize(pAudioClient, AUDCLNT_SHAREMODE_SHARED, 0, 10000000,   // 1秒的缓冲区
            0, pwfx, NULL);
    IAudioRenderClient *pRenderClient;
    pAudioClient->lpVtbl->GetService(pAudioClient, &IID_IAudioRenderClient, (LPVOID *)&pRenderClient);
    UINT32 numBufferFrames;
    pAudioClient->lpVtbl->GetBufferSize(pAudioClient, &numBufferFrames);
    pAudioClient->lpVtbl->Start(pAudioClient);
    DWORD dwFlags = 0;
    while((dwFlags & AUDCLNT_BUFFERFLAGS_SILENT) == 0) {
        UINT32 numPaddingFrames;
        pAudioClient->lpVtbl->GetCurrentPadding(pAudioClient, &numPaddingFrames);
        if(numBufferFrames > numPaddingFrames) {
            BYTE *pData;
            pRenderClient->lpVtbl->GetBuffer(pRenderClient, numBufferFrames - numPaddingFrames, &pData);
            LoadData(pData, numBufferFrames - numPaddingFrames, pwfx, &dwFlags);
            pRenderClient->lpVtbl->ReleaseBuffer(pRenderClient, numBufferFrames - numPaddingFrames, dwFlags);
        }
        Sleep(500);     // 半秒醒过来填一次缓冲区
    }
    pAudioClient->lpVtbl->Stop(pAudioClient);
    pRenderClient->lpVtbl->Release(pRenderClient);
    CoTaskMemFree(pwfx);
    pAudioClient->lpVtbl->Release(pAudioClient);
    pDevice->lpVtbl->Release(pDevice);
    pEnumerator->lpVtbl->Release(pEnumerator);
    CoUninitialize();
    return 0;
}

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
额外减小 + 1 + 1 鱼C有你更精彩^_^

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 21:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表