pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

自動(dòng)將位圖修剪到最小尺寸?

Automatically trim a bitmap to minimum size?(自動(dòng)將位圖修剪到最小尺寸?)
本文介紹了自動(dòng)將位圖修剪到最小尺寸?的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

假設(shè)我有一個(gè) 32bpp ARGB 模式的 System.Drawing.Bitmap.這是一個(gè)大的位圖,但它主要是完全透明的像素,中間有一個(gè)相對較小的圖像.

Suppose I have a System.Drawing.Bitmap in 32bpp ARGB mode. It's a large bitmap, but it's mostly fully transparent pixels with a relatively small image somewhere in the middle.

檢測真實(shí)"圖像邊界的快速算法是什么,這樣我就可以剪掉它周圍的所有透明像素?

What is a fast algorithm to detect the borders of the "real" image, so I can crop away all the transparent pixels from around it?

或者,.Net 中是否已經(jīng)有一個(gè)函數(shù)可以用于此目的?

Alternatively, is there a function already in .Net that I can use for this?

推薦答案

基本思想是檢查圖像的每個(gè)像素點(diǎn),找到圖像的上、左、右、下邊界.要有效地執(zhí)行此操作,請不要使用速度很慢的 GetPixel 方法.改用 LockBits.

The basic idea is to check every pixel of the image to find the top, left, right and bottom bounds of the image. To do this efficiently, don't use the GetPixel method, which is pretty slow. Use LockBits instead.

這是我想出的實(shí)現(xiàn):

static Bitmap TrimBitmap(Bitmap source)
{
    Rectangle srcRect = default(Rectangle);
    BitmapData data = null;
    try
    {
        data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        byte[] buffer = new byte[data.Height * data.Stride];
        Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
        int xMin = int.MaxValue;
        int xMax = 0;
        int yMin = int.MaxValue;
        int yMax = 0;
        for (int y = 0; y < data.Height; y++)
        {
            for (int x = 0; x < data.Width; x++)
            {
                byte alpha = buffer[y * data.Stride + 4 * x + 3];
                if (alpha != 0)
                {
                    if (x < xMin) xMin = x;
                    if (x > xMax) xMax = x;
                    if (y < yMin) yMin = y;
                    if (y > yMax) yMax = y;
                }
            }
        }
        if (xMax < xMin || yMax < yMin)
        {
            // Image is empty...
            return null;
        }
        srcRect = Rectangle.FromLTRB(xMin, yMin, xMax, yMax);
    }
    finally
    {
        if (data != null)
            source.UnlockBits(data);
    }

    Bitmap dest = new Bitmap(srcRect.Width, srcRect.Height);
    Rectangle destRect = new Rectangle(0, 0, srcRect.Width, srcRect.Height);
    using (Graphics graphics = Graphics.FromImage(dest))
    {
        graphics.DrawImage(source, destRect, srcRect, GraphicsUnit.Pixel);
    }
    return dest;
}

它可能可以優(yōu)化,但我不是 GDI+ 專家,所以這是我能做的最好的,無需進(jìn)一步研究...

It can probably be optimized, but I'm not a GDI+ expert, so it's the best I can do without further research...

實(shí)際上,有一種簡單的方法可以優(yōu)化它,即不掃描圖像的某些部分:

actually, there's a simple way to optimize it, by not scanning some parts of the image :

  1. 從左到右掃描,直到找到一個(gè)不透明的像素;將 (x, y) 存入 (xMin, yMin)
  2. 從上到下掃描,直到找到一個(gè)不透明的像素(僅適用于 x >= xMin);將 y 存入 yMin
  3. 從右向左掃描,直到找到一個(gè)不透明的像素(僅適用于 y >= yMin);將 x 存入 xMax
  4. 從下往上掃描,直到找到一個(gè)不透明的像素(僅適用于 xMin <= x <= xMax);將 y 存入 yMax

<小時(shí)>

這是上述方法的實(shí)現(xiàn):


here's an implementation of the approach above:

static Bitmap TrimBitmap(Bitmap source)
{
    Rectangle srcRect = default(Rectangle);
    BitmapData data = null;
    try
    {
        data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
        byte[] buffer = new byte[data.Height * data.Stride];
        Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);

        int xMin = int.MaxValue,
            xMax = int.MinValue,
            yMin = int.MaxValue,
            yMax = int.MinValue;

        bool foundPixel = false;

        // Find xMin
        for (int x = 0; x < data.Width; x++)
        {
            bool stop = false;
            for (int y = 0; y < data.Height; y++)
            {
                byte alpha = buffer[y * data.Stride + 4 * x + 3];
                if (alpha != 0)
                {
                    xMin = x;
                    stop = true;
                    foundPixel = true;
                    break;
                }
            }
            if (stop)
                break;
        }

        // Image is empty...
        if (!foundPixel)
            return null;

        // Find yMin
        for (int y = 0; y < data.Height; y++)
        {
            bool stop = false;
            for (int x = xMin; x < data.Width; x++)
            {
                byte alpha = buffer[y * data.Stride + 4 * x + 3];
                if (alpha != 0)
                {
                    yMin = y;
                    stop = true;
                    break;
                }
            }
            if (stop)
                break;
        }

        // Find xMax
        for (int x = data.Width - 1; x >= xMin; x--)
        {
            bool stop = false;
            for (int y = yMin; y < data.Height; y++)
            {
                byte alpha = buffer[y * data.Stride + 4 * x + 3];
                if (alpha != 0)
                {
                    xMax = x;
                    stop = true;
                    break;
                }
            }
            if (stop)
                break;
        }

        // Find yMax
        for (int y = data.Height - 1; y >= yMin; y--)
        {
            bool stop = false;
            for (int x = xMin; x <= xMax; x++)
            {
                byte alpha = buffer[y * data.Stride + 4 * x + 3];
                if (alpha != 0)
                {
                    yMax = y;
                    stop = true;
                    break;
                }
            }
            if (stop)
                break;
        }

        srcRect = Rectangle.FromLTRB(xMin, yMin, xMax, yMax);
    }
    finally
    {
        if (data != null)
            source.UnlockBits(data);
    }

    Bitmap dest = new Bitmap(srcRect.Width, srcRect.Height);
    Rectangle destRect = new Rectangle(0, 0, srcRect.Width, srcRect.Height);
    using (Graphics graphics = Graphics.FromImage(dest))
    {
        graphics.DrawImage(source, destRect, srcRect, GraphicsUnit.Pixel);
    }
    return dest;
}

當(dāng)然,如果非透明部分很小,則不會(huì)有明顯的增益,因?yàn)樗匀粫?huì)掃描大部分像素.但如果它很大,則只會(huì)掃描不透明部分周圍的矩形.

There won't be a significant gain if the non-transparent part is small of course, since it will still scan most of the pixels. But if it's big, only the rectangles around the non-transparent part will be scanned.

這篇關(guān)于自動(dòng)將位圖修剪到最小尺寸?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

Right-click on a Listbox in a Silverlight 4 app(右鍵單擊 Silverlight 4 應(yīng)用程序中的列表框)
WPF c# webbrowser scrolls over top menu(WPF c# webbrowser 在頂部菜單上滾動(dòng))
C# Console app - How do I make an interactive menu?(C# 控制臺應(yīng)用程序 - 如何制作交互式菜單?)
How to avoid duplicate form creation in .NET Windows Forms?(如何避免在 .NET Windows Forms 中創(chuàng)建重復(fù)的表單?)
UI Automation Control Desktop Application and Click on Menu Strip(UI自動(dòng)化控制桌面應(yīng)用程序并單擊菜單條)
Removing thin border around the menuitems(刪除菜單項(xiàng)周圍的細(xì)邊框)
主站蜘蛛池模板: 东莞猎头公司_深圳猎头公司_广州猎头公司-广东万诚猎头提供企业中高端人才招聘服务 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 武汉刮刮奖_刮刮卡印刷厂_为企业提供门票印刷_武汉合格证印刷_现金劵代金券印刷制作 - 武汉泽雅印刷有限公司 | 高速混合机_锂电混合机_VC高效混合机-无锡鑫海干燥粉体设备有限公司 | 特种阀门-调节阀门-高温熔盐阀-镍合金截止阀-钛阀门-高温阀门-高性能蝶阀-蒙乃尔合金阀门-福建捷斯特阀门制造有限公司 | 强效碱性清洗剂-实验室中性清洗剂-食品级高纯氮气发生器-上海润榕科学器材有限公司 | 冷却塔风机厂家_静音冷却塔风机_冷却塔电机维修更换维修-广东特菱节能空调设备有限公司 | 色谱柱-淋洗液罐-巴罗克试剂槽-巴氏吸管-5ml样品瓶-SBS液氮冻存管-上海希言科学仪器有限公司 | 土壤水分自动监测站-SM150便携式土壤水分仪-铭奥仪器 | 杭州|上海贴标机-百科| 三板富 | 专注于新三板的第一垂直服务平台 | 广东青藤环境科技有限公司-水质检测 | 礼仪庆典公司,礼仪策划公司,庆典公司,演出公司,演艺公司,年会酒会,生日寿宴,动工仪式,开工仪式,奠基典礼,商务会议,竣工落成,乔迁揭牌,签约启动-东莞市开门红文化传媒有限公司 | 股指期货-期货开户-交易手续费佣金加1分-保证金低-期货公司排名靠前-万利信息开户 | 广州展览制作工厂—[优简]直营展台制作工厂_展会搭建资质齐全 | 亿诺千企网-企业核心产品贸易 | 升降机-高空作业车租赁-蜘蛛车-曲臂式伸缩臂剪叉式液压升降平台-脚手架-【普雷斯特公司厂家】 | DWS物流设备_扫码称重量方一体机_快递包裹分拣机_广东高臻智能装备有限公司 | 护腰带生产厂家_磁石_医用_热压护腰_登山护膝_背姿矫正带_保健护具_医疗护具-衡水港盛 | 冷水机-工业冷水机-冷水机组-欧科隆品牌保障 | 自动记录数据电子台秤,记忆储存重量电子桌称,设定时间记录电子秤-昆山巨天 | 缠膜机|缠绕包装机|无纺布包装机-济南达伦特机械设备有限公司 | 北京律师事务所_房屋拆迁律师_24小时免费法律咨询_云合专业律师网 | 二手注塑机回收_旧注塑机回收_二手注塑机买卖 - 大鑫二手注塑机 二手光谱仪维修-德国OBLF光谱仪|进口斯派克光谱仪-热电ARL光谱仪-意大利GNR光谱仪-永晖检测 | 湖南印刷厂|长沙印刷公司|画册印刷|挂历印刷|台历印刷|杂志印刷-乐成印刷 | 搜活动房网—活动房_集装箱活动房_集成房屋_活动房屋 | 高尔夫球杆_高尔夫果岭_高尔夫用品-深圳市新高品体育用品有限公司 | 雨燕360体育免费直播_雨燕360免费NBA直播_NBA篮球高清直播无插件-雨燕360体育直播 | 深圳标识制作公司-标识标牌厂家-深圳广告标识制作-玟璟广告-深圳市玟璟广告有限公司 | 天品互联-北京APP开发公司-小程序开发制作-软件开发 | 山东成考网-山东成人高考网| 二手回收公司_销毁处理公司_设备回收公司-找回收信息网 | 气动隔膜阀_气动隔膜阀厂家_卫生级隔膜阀价格_浙江浙控阀门有限公司 | 北京中创汇安科贸有限公司 | 冷柜风机-冰柜电机-罩极电机-外转子风机-EC直流电机厂家-杭州金久电器有限公司 | 炒货机-炒菜机-炒酱机-炒米机@霍氏机械 | 寮步纸箱厂_东莞纸箱厂 _东莞纸箱加工厂-东莞市寮步恒辉纸制品厂 | 台式恒温摇床价格_大容量恒温摇床厂家-上海量壹科学仪器有限公司 | 【365公司转让网】公司求购|转让|资质买卖_股权转让交易平台 | 耐火浇注料价格-高强高铝-刚玉碳化硅耐磨浇注料厂家【直销】 | 包装设计公司,产品包装设计|包装制作,包装盒定制厂家-汇包装【官方网站】 |